dij是单源的,只是从一个顶点出发到其它点的最短距离,并且它的全值都是正的,不能够有负值;
Bellman-ford 也是单源的,但是他能够完成负权值的图,这是dij无法达到的,并且能够判断是否存在负环,经过修改可以求最长路;
SPFA是在Bellman-ford上优化的,所以跟快;
floyd算法可以求出任意两点的最短路,索然dij对每个点一次for也能求出,但是复杂度O(n^3)或O(n^2+ne),一次floyd也是O(n^3),
但是floyd更加易懂,简洁;floyd允许带负值的边,但不能有回路(环);floyd很灵活,可以多种变换;
(个人的理解 不是很深,只懂一点)
1 poj3268 2 很多牛,要到x这个点,来回多少时间; 3 正向,反向2次SPFA,2个值相加,然后取最大; 4 #include<STDIO.H> 5 #include<string.h> 6 #include<queue> 7 #define INF 999999999 8 using namespace std; 9 struct node 10 { 11 int v; 12 int val; 13 int next; 14 }edge1[100003],edge2[100003]; 15 int head1[1003],dis1[1003],head2[1003],dis2[1003]; 16 int n,m,t,index1,index2; 17 void add1(int x,int y,int z) 18 { 19 int i,j; 20 edge1[index1].v=y; 21 edge1[index1].val=z; 22 edge1[index1].next=head1[x]; 23 head1[x]=index1++; 24 } 25 void add2(int x,int y,int z) 26 { 27 int i,j; 28 edge2[index2].v=y; 29 edge2[index2].val=z; 30 edge2[index2].next=head2[x]; 31 head2[x]=index2++; 32 } 33 void SPFA1(int u) 34 { 35 int vis[1003],i,j; 36 memset(vis,0,sizeof(vis)); 37 queue<int>q; 38 for(i=1;i<=n;i++) 39 dis1[i]=INF; 40 dis1[u]=0; 41 vis[u]=1; 42 q.push(u); 43 while(!q.empty()) 44 { 45 int v=q.front(); 46 q.pop(); 47 vis[v]=0; 48 for(i=head1[v];i!=-1;i=edge1[i].next) 49 { 50 int tmp=edge1[i].v; 51 if(dis1[tmp]>dis1[v]+edge1[i].val) 52 { 53 dis1[tmp]=dis1[v]+edge1[i].val; 54 if(!vis[tmp]) 55 { 56 q.push(tmp); 57 vis[tmp]=1; 58 } 59 } 60 } 61 } 62 } 63 void SPFA2(int u) 64 { 65 int vis[1003],i,j; 66 memset(vis,0,sizeof(vis)); 67 queue<int>q; 68 for(i=1;i<=n;i++) 69 dis2[i]=INF; 70 dis2[u]=0; 71 vis[u]=1; 72 q.push(u); 73 while(!q.empty()) 74 { 75 int v=q.front(); 76 q.pop(); 77 vis[v]=0; 78 for(i=head2[v];i!=-1;i=edge2[i].next) 79 { 80 int tmp=edge2[i].v; 81 if(dis2[tmp]>dis2[v]+edge2[i].val) 82 { 83 dis2[tmp]=dis2[v]+edge2[i].val; 84 if(!vis[tmp]) 85 { 86 q.push(tmp); 87 vis[tmp]=1; 88 } 89 } 90 } 91 } 92 } 93 int main() 94 { 95 int i,j; 96 while(scanf("%d%d%d",&n,&m,&t)!=EOF) 97 { 98 index1=index2=1; 99 memset(dis1,0,sizeof(dis1)); 100 memset(head1,-1,sizeof(head1)); 101 memset(dis2,0,sizeof(dis2)); 102 memset(head2,-1,sizeof(head2)); 103 for(i=0;i<m;i++) 104 { 105 int x,y,z; 106 scanf("%d%d%d",&x,&y,&z); 107 add1(x,y,z); 108 add2(y,x,z); 109 } 110 111 SPFA1(t); 112 113 /*for(i=1;i<=n;i++) 114 printf("%d ",dis1[i]); 115 printf("\n");*/ 116 117 SPFA2(t); 118 119 /*for(i=1;i<=n;i++) 120 printf("%d ",dis2[i]);printf("\n");*/ 121 122 int max=0; 123 for(i=1;i<=n;i++) 124 { 125 if(max<dis2[i]+dis1[i]) 126 max=dis2[i]+dis1[i]; 127 } 128 printf("%d\n",max); 129 } 130 }
/*poj2570 floyd算法来找到所有可能的路径; 用二进制26位表示路径; 0000000000.......111,这个表示abc; floyd时 map[i][j]|=map[i][k]&map[k][j]; |表示有新的路径 那么就合并路径,&表示存在这个路; 最后遍历26个字母即可;*/ //poj2570 #include<stdio.h> #include<string.h> int map[203][203]; int n; int main() { int i,j,l,x,y; while(scanf("%d",&n)!=EOF) { if(!n)break; memset(map,0,sizeof(map)); char s[50]; while(1) { x,y; scanf("%d %d",&x,&y); if(x==0&&y==0) break; scanf("%s",s); l=strlen(s); for(i=0;i<l;i++) { map[x][y]|=1<<(s[i]-‘a‘); } } //floyd for(i=1;i<=n;i++) for(j=1;j<=n;j++) for(int k=1;k<=n;k++) { map[j][k]|=(map[j][i] & map[i][k]); } char ii; while(1) { scanf("%d %d",&x,&y); if(x==0&&y==0)break; for(ii=‘a‘;ii<=‘z‘;ii++) { if(map[x][y] & (1<<(ii-‘a‘))) { printf("%c",ii); } } if(!map[x][y]) { printf("-"); } putchar(‘\n‘); } putchar(‘\n‘); } } //poj2263 /*floyd来求解最大能够载重; 应为A->C可以有2种情况 A->B,B->C或者A->C,要得到A->C这条道路最大的载重量,由于A,B,C这三条路的载重不同, 所以要找出A->B,B->C的最小载重,因为如果取大的,另外一条就不能了,然后再取直接到和间接到的最大值, 此时可以用floyd来解决问题;*/ #include<stdio.h> #include<string.h> #define INF 99999999 int map[205][205]; int num;//统计city int n,m; char s[20],e[20]; char in1[30],in2[30]; char city[205][50]; int max(int x,int y) { return x>y?x:y; } int min(int x,int y) { return x<y?x:y; } int inset(char a[]) { int i,j; for(i=0;i<num;i++) { if(strcmp(city[i],a)==0) { return i; } } num++; strcpy(city[i],a); return i; } int floyd() { int i,j,k; for(i=0;i<n;i++) for(j=0;j<n;j++) for(k=0;k<n;k++) { map[j][k]=max(map[j][k],min(map[j][i],map[i][k])); } int x,y; x=inset(s); y=inset(e); return map[x][y]; } int main() { int i,j; int ff=0; while(scanf("%d%d",&n,&m)!=EOF) { if(!n&&!m)break; memset(map,0,sizeof(map)); num=0; for(i=0;i<=n;i++) map[i][i]=INF; for(i=0;i<m;i++) { int z; scanf("%s %s %d",in1,in2,&z); int x,y; x=inset(in1); y=inset(in2); map[x][y]=map[y][x]=z; } scanf("%s %s",s,e); int ans=floyd(); printf("Scenario #%d\n",++ff); printf("%d tons\n",ans); printf("\n"); } }
时间: 2024-11-05 20:41:19