* P1119 reconstruction [floyd]

Topic background

B B region after the earthquake, all the villages have caused some damage, but the quake did not cause any impact on the road. But before the village rebuilt, all the roads of the village and did not complete the reconstruction are not open to traffic. In other words, the only road connecting the village to complete the reconstruction of two of the opening, only to reach the complete reconstruction of the village.

Title Description

Given B B region village number N N , numbered from 00 to village. 1-N N -1, and all of M M is a length of two-way roads, highways. And gives the first i i villages to complete the reconstruction of the time t_i t i , you can be considered simultaneously and beginning reconstruction of the t_i t i days to complete the reconstruction, and to open to traffic in the day. If t_i * t ** i is 00 then the earthquake did not cause damage to this region, a beginning can be opened to traffic. After you have Q Q a inquiry (the X-, y, t) ( the X- , y , t ), for each challenge you to answer the first t t day, from the village the X- the X- shortest path length y is the number of villages. If you can not find from the X- the X- villages to the y- the y- path villages, reconstruction has been completed through a number of villages, villages or the X- the X- or villages in the y- the y-* not yet complete reconstruction in day t, we need to return -1-1.

Resolve

poisonous. T dij kick off pay up belatedly, this problem starting a floyd.

First, complexity easy to reach dij \ (O (Q (n-m +) ~ n-log) \) , for the (m \) \ larger this question, it reaches the \ (1E9 \) level, apparently It will be fried, then oxygen can not too.

T first four points out of dij Tieshanglai:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 201
#define M 10010
#define MOD 2520
#define E 1e-12
#define ri register int
using namespace std;
//start from 0
inline int read()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct rec{
    int next,ver,edge;
}g[M<<1];
int head[N],tot,n,m,d[N],t[M];
bool v[N],ve[M<<1];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
inline void add(int x,int y,int val)
{
    g[++tot].ver=y,g[tot].edge=val;
    g[tot].next=head[x],head[x]=tot;
}
inline void dij(int x)
{
    memset(v,0,sizeof(v));
    memset(d,0x3f,sizeof(d));
    d[x]=0;q.push(make_pair(0,x));
    while(q.size()){
        int index=q.top().second;q.pop();
        if(v[index]||!ve[index]) continue;
        v[index]=1;
        for(ri i=head[index];i;i=g[i].next){
            int y=g[i].ver,z=g[i].edge;
            if(d[y]>d[index]+z&&ve[y]){
                d[y]=d[index]+z;
                q.push(make_pair(d[y],y));
            }
        }
    }
}
int main()
{
    n=read(),m=read();
    for(int i=0;i<n;++i) t[i]=read();
    t[n]=INF;
    for(ri i=1;i<=m;++i){
        int u,v,val;
        u=read(),v=read(),val=read();
        add(u,v,val),add(v,u,val);
    }
    int q,nowc=0;
    q=read();
    while(q--){
        int u,v,ti;
        u=read(),v=read(),ti=read();
        while(t[nowc]<=ti) ve[nowc]=1,nowc++;
        dij(u);
        if(d[v]==INF) printf("-1\n");
        else printf("%d\n",d[v]);
    }
    return 0;   
} 

Then talk about positive solutions:

First, a look at the questions asked each shortest path between two points, think floyd, but you conscientiously run a \ (Q \) times on the complexity of the \ (O (the n-^ 4) \) , the results were even as good as dij.

If the in-depth understanding of the working principle floyd, you will know that it is in accordance with the idea dp each of any two points, find another two points different from the midpoint to update the shortest distance. Carefully observed, in this question, add up to a second point, we might as well join in every time point, took this new point as intermediate point to update the shortest, apparently with the original floyd is no difference.

As a result, the complexity was reduced to \ (O (the n-^ 3) \) , the maximum level is only about \ (1E7 \) , Kaka often can go through this problem.

Oxygen, after the card often, efficiency is quite substantial:

\ (85 ms, 916KB \) , and even lined up the second page of the optimal solution. . .

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 201
#define M 10010
#define MOD 2520
#define E 1e-12
#define ri register int
using namespace std;
//start from 0
inline int read()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int g[N][N],n,m,t[M];
inline void fly(int k)
{
    for(int i=0;i<n;++i)
        for(int j=0;j<n;++j)
            g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
int main()
{
    n=read(),m=read();
    for(int i=0;i<n;++i) t[i]=read();
    t[n]=INF;
    for(int i=0;i<n;++i)
        for(int j=0;j<n;++j) g[i][j]=INF;
    for(int i=0;i<n;++i) g[i][i]=0;
    for(ri i=1;i<=m;++i){
        int u,v,val;
        u=read(),v=read(),val=read();
        g[u][v]=g[v][u]=val;
    }
    int q,nowc=0;
    q=read();
    for(int i=1;i<=q;++i){
        int u,v,ti;
        u=read(),v=read(),ti=read();
        while(t[nowc]<=ti) fly(nowc),nowc++;
        if(t[u]>ti||t[v]>ti) printf("-1\n");
        else if(g[u][v]==INF) printf("-1\n");
        else printf("%d\n",g[u][v]);
    }
    return 0;   
} 

Guess you like

Origin www.cnblogs.com/DarkValkyrie/p/11402386.html