每条公路用三个整数(x,y,z)来,即城市X与城市Y之间可以修一条高速公路,需要Z的花费。出于节约,政府希望从这些公路出选一些出来修建,使总开支最小。并保证建造后任意两个城市之间都可以直接或间接相连。但往往只考虑费用并不能得到最有价值的方案,例如城市A与城市B之间活动较频繁为了方便这两个城市间交通运输,应修建一条AB间直达的高速公路。于是政府考试将某些公路的建造开支降低 ,使得修筑这条公路后,仍然可以得到一个总开支最低(甚至比原来更低)方案,你的任务就是判断这样的计划可不可行。
思路:mx[i][j]记录顶点i到顶点j路径上最长的边,如果修改的费用c大于最长边,则不可以修改。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=1005; int n,m,k; int G[maxn][maxn],mx[maxn][maxn]; struct Edge{ int u; int v; int w; bool operator < (const Edge &e) const { return w<e.w; } }edge[maxn*100]; int e; void init(){ e=1; memset(G,INF,sizeof(G)); memset(mx,0,sizeof(mx)); } void addEdge(int u,int v,int w){ edge[e].u=u; edge[e].v=v; edge[e].w=w; e++; } int pre[maxn],low[maxn],vis[maxn]; void Prim(){ memset(vis,0,sizeof(vis)); int pos=1; for(int i=1;i<=n;i++) low[i]=G[pos][i]; low[pos]=0,vis[pos]=1,pre[pos]=1; for(int i=1;i<=n;i++){ int min=INF; for(int j=1;j<=n;j++){ if(!vis[j]&&low[j]<min){ min=low[pos=j]; } } for(int j=1;j<=n;j++){ if(vis[j]){ mx[pos][j]=max(mx[j][pre[pos]],low[pos]); mx[j][pos]=mx[pos][j]; } } vis[pos]=1; for(int j=1;j<=n;j++){ if(!vis[j]&&low[j]>G[pos][j]){ low[j]=G[pos][j]; pre[j]=pos; } } } } int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif while(~scanf("%d%d%d",&n,&m,&k)){ init(); for(int i=1;i<=n;i++) G[i][i]=0; int u,v,w; while(m--){ scanf("%d%d%d",&u,&v,&w); addEdge(u,v,w); G[u][v]=G[v][u]=min(G[u][v],w); } Prim(); int num,c; while(k--){ scanf("%d%d",&num,&c); if(mx[edge[num].u][edge[num].v]<c) printf("No\n"); else printf("Yes\n"); } } return 0; }