SDUTOJ2929 ——人活着系列之芳姐和芳姐的猪 暴力SPFA和弗洛伊德(最短路)

来源:互联网 发布:学校档案管理系统软件 编辑:程序博客网 时间:2024/04/30 03:42

人活着系列之芳姐和芳姐的猪

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

芳姐特别喜欢猪,所以,她特意养了m个猪圈,顺便在k条无向边,每条边有都有起点v,距离.....芳姐和猪们约定好,每天去一个固定猪圈去吃饭,芳姐为了不累着她可爱的猪们,想知道所有的猪吃饭走的最短路程是多少?

输入

 第一行,猪的个数mk(1<=k<=1200).(猪的编号为1..m)

N+1N头猪所在的猪圈号n+k+1行:u1<=w<=255)

m个猪圈连通。

输出

 

示例输入

3 4 52341 2 11 3 52 3 72 4 33 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;}





0 0
原创粉丝点击