题意:给你n个点,m个遍,q次询问。问你改了第i条边的权值,他能否使得最小价格降低,或不变。
想法:是次小生成树的变形,很简单,但是我被prime恶心死了。
#include<iostream> #include<cstring> #include<cstdio> #include<cassert> #define inf 0x7fffffff using namespace std; const int nodes=1000+50; const int edges=1000000+500; int n,m,q; int map[nodes][nodes]; struct node { int u,v; }e[edges]; int vis[nodes],pre[nodes]; int maxx[nodes][nodes]; int Min(int a,int b) { if(a<b) return a; return b; } void Input() { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) map[i][j]=0; else map[i][j]=inf; } } for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); e[i].u=a;e[i].v=b; map[a][b]=map[b][a]=Min(map[a][b],c); } } int Max(int a,int b) { if(a>b) return a; return b; } void prime(){ int i,j,t,loc; int dis[nodes]; memset(vis,0,sizeof(vis)); memset(maxx,0,sizeof(maxx)); for(i=1;i<=n;i++){ dis[i]=inf; } dis[1]=0;loc=1;vis[1]=1; for(i=1;i<n;i++){ for(j=1;j<=n;j++){ if(!vis[j]&&map[loc][j]<dis[j]){ dis[j]=map[loc][j],pre[j]=loc; } } int min=inf; for(j=1;j<=n;j++){ if(!vis[j]&&dis[j]<min) min=dis[loc=j]; } for(j=1;j<=n;j++) if(vis[j]){ maxx[loc][j]=max(maxx[j][pre[loc]],dis[loc]); maxx[j][loc]=maxx[loc][j]; } vis[loc]=1; } } void treatment() { while(q--) { int a,b; scanf("%d%d",&a,&b); if(b<=maxx[e[a].u][e[a].v]) printf("Yes\n"); else printf("No\n"); } } int main() { while(~scanf("%d%d%d",&n,&m,&q)) { Input(); prime(); treatment(); } return 0; }
注意:vis的更新。
#include<iostream> #include<cstring> #include<cstdio> #include<cassert> #define inf 0x7fffffff using namespace std; const int nodes=1000+5; const int edges=1000000+500; int n,m,q; int map[nodes][nodes]; struct node { int u,v; }e[edges]; int maxx[nodes][nodes]; int Min(int a,int b) { if(a<b) return a; return b; } void Input() { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) map[i][j]=0; else map[i][j]=inf; } } for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); e[i].u=a;e[i].v=b; map[a][b]=map[b][a]=Min(map[a][b],c); } } int Max(int a,int b) { if(a>b) return a; return b; } void prime() { memset(maxx,0,sizeof(maxx)); int pre[nodes],low[nodes],vis[nodes]; for(int i=1;i<=n;i++) { low[i]=map[1][i]; pre[i]=1; vis[i]=0; } low[1]=0; vis[1]=1; pre[1]=-1; for(int i=2;i<=n;i++) { int minn=inf; int pos; for(int j=1;j<=n;j++) { if(!vis[j]&&minn>low[j]) { minn=low[j]; pos=j; } } vis[pos]=1; for(int j=1;j<=n;j++) { if(vis[j]&&j!=pos) { maxx[pos][j]=maxx[j][pos]=Max(maxx[j][pre[pos]],low[pos]); } if(!vis[j]&&low[j]>map[pos][j]) { low[j]=map[pos][j]; pre[j]=pos; } } } } void treatment() { while(q--) { int a,b; scanf("%d%d",&a,&b); if(b<=maxx[e[a].u][e[a].v]) printf("Yes\n"); else printf("No\n"); } } int main() { while(~scanf("%d%d%d",&n,&m,&q)) { Input(); prime(); treatment(); } return 0; }