[P1119]灾后重建

来源:互联网 发布:access数据库拆分字段 编辑:程序博客网 时间:2024/06/08 09:39

原题链接

一开始直接想跑最短路
看了看询问次数
放弃了
然后果断看了题解

Floyd
用啥都不会用它的好吗
平常的最劣选择
但是
它就是正解
不得了

Floyd的原理
就是枚举中点
这里
因为出题人
已经把询问排好了序
只需要判断中点
有没有重建完成
把它加入图中

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<vector>#include<queue>using namespace std;struct maki{    int p1,p2,tim;}que[50005];int dis[205][205],i,j,k,p,n,m,ti[205],x,y,t,a,b,w,vis[205],q;int main(){    scanf("%d%d",&n,&m);    for(i=0;i<n;i++)        for(j=0;j<n;j++)            dis[i][j]=1e6;      for(i=0;i<n;i++) scanf("%d",&ti[i]);            for(i=1;i<=m;i++)    {        scanf("%d%d%d",&a,&b,&w);        dis[a][b]=w;        dis[b][a]=w;    }       scanf("%d",&q);    for(i=1;i<=q;i++)    {        scanf("%d%d%d",&x,&y,&t);        que[i].p1=x;        que[i].p2=y;        que[i].tim=t;    }    for(p=1;p<=q;p++)    {        x=que[p].p1;        y=que[p].p2;        if(ti[x]>que[p].tim||ti[y]>que[p].tim)        {            printf("-1\n");            continue;        }           for(k=0;k<n;k++)            if((ti[k]<=que[p].tim)&&(!vis[k]))            {                vis[k]=1;                for(i=0;i<n;i++)                    for(j=0;j<n;j++)                        if(i!=j&&j!=k&&k!=i)                            dis[i][j]=min(dis[i][j],dis[i][k]+dis[j][k]);            }        if(dis[x][y]>=1e6) printf("-1\n");        else printf("%d\n",dis[x][y]);    }    return 0;}
0 0
原创粉丝点击