芳姐特别喜欢猪,所以,她特意养了m个猪圈,顺便在k条无向边,每条边有都有起点v,距离.....芳姐和猪们约定好,每天去一个固定猪圈去吃饭,芳姐为了不累着她可爱的猪们,想知道所有的猪吃饭走的最短路程是多少?
N+1行N头猪所在的猪圈号第n+k+1行:u、1<=w<=255)
m个猪圈连通。
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5
8
这个题分析一下题意就知道是多源最短路,可是我用弗洛伊德算法没能AC,后来问了问叶神,叶神给出一个思路,用SPFA(因为最短路中,SPFA的算法效率比较高)算出,1 ---- m这些点到每个点的最短路,这样这个题的最大问题就解决了。。。。。
#include <stdio.h> #include <string.h> #include <queue> using namespace std; const int inf = 1 << 28; struct node { int v; int w; int next; }ls[360010]; int hs[610]; int head[610]; int zd[610][610]; bool vis[610]; int num; queue <int> q; void creat(int x,int y,int z) { ls[num].v = y; ls[num].w = z; ls[num].next = head[x]; head[x] = num++; } void spfa(int s,int m) { int t; memset(vis,false,sizeof(vis)); for(int i = 0;i <= m;i++) zd[s][i] = inf; while(!q.empty()) q.pop(); zd[s][s] = 0; vis[s] = true; q.push(s); while(!q.empty()) { t = q.front(); q.pop(); int x = t; for(int i = head[x];~i;i = ls[i].next) { int y = ls[i].v; if(zd[s][y] > zd[s][x] + ls[i].w ) { zd[s][y] = zd[s][x] + ls[i].w; if(!vis[y]) { vis[y] = true; q.push(y); } } } vis[x] = false; } } int main() { int n,m,k; int np,x,y,z,mn; while(~scanf("%d%d%d",&n,&m,&k)) { mn = inf; num = 0; memset(hs,0,sizeof(hs)); memset(head,-1,sizeof(head)); for(int i = 0;i < n;i++) { scanf("%d",&np); hs[np]++; } for(int i = 0;i < k;i++) { scanf("%d%d%d",&x,&y,&z); creat(x,y,z); creat(y,x,z); } for(int i = 1;i <= m;i++) { spfa(i,m); } int sum; for(int i = 1;i <= m;i++) { sum = 0; for(int j = 1;j <= m;j++) { if(hs[j]) sum += hs[j] * zd[i][j]; } if(mn > sum) mn = sum; } printf("%d\n",mn); } return 0; }
弗洛伊德来了:
#include <stdio.h> #include <string.h> const int inf = 1 << 28; int hs[610]; int mp[610][610]; int n,m,k; int main() { int np,x,y,z; while(~scanf("%d%d%d",&n,&m,&k)) { memset(hs,0,sizeof(hs)); for(int i = 1;i <= m;i++) { for(int j = 1;j <= m;j++) { mp[i][j] = inf; } mp[i][i] = 0; } for(int i = 0;i < n;i++) { scanf("%d",&np); hs[np]++; } for(int i = 0;i < k;i++) { scanf("%d%d%d",&x,&y,&z); if(mp[x][y] > z) { mp[x][y] = z; mp[y][x] = z; } } for(x = 1;x <= m;x++) { for(y = 1;y <= m;y++) { for(z = 1;z <= m;z++) { if(mp[y][z] > mp[y][x] + mp[x][z]) mp[y][z] = mp[y][x] + mp[x][z]; } } } int mn = inf,sum; for(int i = 1;i <= m;i++) { sum = 0; for(int j = 1;j <= m;j++) { if(hs[j]) { sum += hs[j] * mp[i][j]; } } if(mn > sum) mn = sum; } printf("%d\n",mn); } return 0; }