人活着系列之芳姐和芳姐的猪
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
芳姐特别喜欢猪,所以,她特意养了m个猪圈,顺便在k条无向边,每条边有都有起点v,距离.....芳姐和猪们约定好,每天去一个固定猪圈去吃饭,芳姐为了不累着她可爱的猪们,想知道所有的猪吃饭走的最短路程是多少?
输入
第一行,猪的个数m(k(1<=k<=1200).(猪的编号为1..m)
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
提示
来源
cz
这个题分析一下题意就知道是多源最短路,可是我用弗洛伊德算法没能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;
}