题意: 给出一个有N个节点的无向图和 M 条边,每条边都有一个重力承受度,要从中找出一条从 1 节点到 n节点的路径,使得可以经过的车辆载重最大。
分析: 类似于最大流中找增广路,在求最短路的松弛操作上加以修改。
SPFA:
View Code
#include<stdio.h> #include<string.h> #define min(a,b)(a)<(b)?(a):(b) #define clr(x)memset(x,0,sizeof(x)) #define INF 0x1f1f1f1f struct node { int to,next,w; }e[1000005]; int tot; int head[1005]; void add(int s,int u,int wi) { e[tot].w=wi; e[tot].to=u; e[tot].next=head[s]; head[s]=tot++; } int q[100005]; int f[1005]; int v[1005]; int main() { int t,n,i,m,a,b,c,u,k,front,rear,ca=1,flow; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); tot=1; clr(head); clr(v); clr(f); while(m--) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } f[1]=INF; front=rear=0; q[rear++]=1; v[1]=1; while(front<rear) { u=q[front++]; v[u]=0; for(i=head[u];i;i=e[i].next) { k=e[i].to; flow=min(f[u],e[i].w); if(f[k]<flow) { f[k]=flow; if(!v[k]) { q[rear++]=k; v[k]=1; } } } } printf("Scenario #%d:\n",ca++); printf("%d\n\n",f[n]); } return 0;
Dijkstra:
View Code
#include<stdio.h> #include<string.h> #define min(a,b)(a)<(b)?(a):(b) #define clr(x)memset(x,0,sizeof(x)) #define INF 0x1f1f1f1f int f[1005]; struct node { int to,w,next; }e[1000000]; int head[1005]; int tot; void add(int s,int u,int wi) { e[tot].to=u; e[tot].w=wi; e[tot].next=head[s]; head[s]=tot++; } int n; void dijkstra() { int s[1005]; int i,j,k,u,tmp; clr(f); clr(s); tmp=-1; f[1]=INF; for(i=head[1];i;i=e[i].next) { k=e[i].to; f[k]=e[i].w; } for(i=1;i<=n;i++) { u=-1; tmp=-1; for(j=1;j<=n;j++) if(!s[j]&&(u==-1||f[j]>tmp)) { tmp=f[j]; u=j; } s[u]=1; for(j=head[u];j;j=e[j].next) { k=e[j].to; if(!s[k]&&(min(f[u],e[j].w))>f[k]) f[k]=min(f[u],e[j].w); } } } int main() { int i,j,a,b,c,k,m,t,ca=1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); tot=1; clr(head); while(m--) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } dijkstra(); printf("Scenario #%d:\n",ca++); printf("%d\n\n",f[n]); } return 0; }