欢迎光临散文网 会员登陆 & 注册

P1119 灾后重建

2023-03-18 18:59 作者:仓鼠翞  | 我要投稿

//https://www.luogu.com.cn/problem/P1119?contestId=96617
//所有与未重建完成的村庄的公路均无法通车。换句话说,只有连接着两个重建完成的村庄的公路才能通车
//只有两个村庄都建好了才可以赋边权
#include<bits/stdc++.h>
#define inf 1e9
using namespace std;
int n,m;
int t[200];
int G[200][200];
int Q;
int tt;
int midG[200][200];
struct Node
{
   int u;
   int v;
   int ttt;
};
Node Ques[50000];

bool visited[200];
int  dist[200];
int dijsktra(int start,int end)
{
   fill(visited,visited+200,false);
   fill(dist,dist+200,inf);
   dist[start]=0;
   for(int i=0;i<n;i++)
   {
       int u=-1;
       int min=inf;
       for(int j=0;j<n;j++)
       {
           if(visited[j]==false&&dist[j]<min)
           {
               u=j;
               min=dist[j];
           }
       }
       if(u==-1) return -1;
       visited[u]=true;
       for(int j=0;j<n;j++)
       {
           if(visited[j]==false&&midG[u][j]!=inf&&dist[j]>dist[u]+midG[u][j])
           {
               dist[j]=dist[u]+midG[u][j];
           }
       }
   }
   return dist[end];
}

int main()
{
   cin>>n>>m;
   for(int i=0;i<n;i++)
       cin>>t[i];
   fill(G[0],G[0]+200*200,inf);
   for(int i=0;i<n;i++)
       G[i][i]=0;
   for(int i=0;i<m;i++)
   {
       int u,v,w;
       cin>>u>>v>>w;
       G[u][v]=G[v][u]=w;
   }
   cin>>Q;
   for(int i=0;i<Q;i++)
   {
       int u,v,ttt;
       cin>>u>>v>>ttt;
       Ques[i].u=u;
       Ques[i].v=v;
       Ques[i].ttt=ttt;
   }
   fill(midG[0],midG[0]+200*200,inf);
   for(int i=0;i<n;i++)
       midG[i][i]=0;
   for(tt=0;tt<=t[n-1];tt++)
   {
       //随时间推移midG中的边逐渐增加
       //如果某个tt时刻i号村子修好了那么释放所有到i或者从i出发的边
       //如果出现tt时刻的询问则查询最短路
       for(int i=0;i<n;i++)
       {
           if(t[i]<=tt)
           {

               //在tt时刻则说明重建时间小于tt的所有村庄都建好了
               //其中最大的tt[i]的村庄编号为i
               for(int x=0;x<=i;x++)
                   for(int y=0;y<=i;y++)
                   {
                       midG[x][y]=G[x][y];
                       midG[y][x]=G[y][x];
                   }
           }
       }
       //查询在tt时刻是否有存在询问
       for(int i=0;i<Q;i++)
       {
           if(Ques[i].ttt==tt)
           {
               int start=Ques[i].u;
               int end  =Ques[i].v;
               //执行dijsktra
               int ans=dijsktra(start,end);
               cout<<ans<<endl;
           }
       }
   }
   return 0;
}
//为什么连样例都没过只有一个没过了

P1119 灾后重建的评论 (共 条)

分享到微博请遵守国家法律