POJ 1511 Invitation Cards

来源:互联网 发布:人工智能 电影在线 编辑:程序博客网 时间:2024/05/16 09:13
/*题意:求1到其他点的最小值的和sum1,再求其他点到1的最小值的和sum2,最后sum=sum1+sum2,输出sum;分析:两个spfa加一个反转图搞定*/#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>#include<iostream>using namespace std;#define LL long longconst int inf=1<<30;const int maxm=1e6+10;int vis[maxm],cnt[maxm],next[maxm],head[maxm],dist[maxm],pre[maxm];int n,m,e;int v[maxm],u[maxm],c[maxm];queue<int>q;void addage(int u,int v,int c){    next[e]=head[u];    head[u]=e++;}void turn()//反转图(***){    int i,k;    for(i=0;i<=m;i++)    {        head[i]=next[i]=-1;    }    for(i=0;i<m;i++)    {        k=v[i];        next[i]=head[k];        head[k]=i;    }}void spfa1(int st){    for(int i=0;i<=n;i++)    {        dist[i]=inf;    }    dist[st]=0;    q.push(st);    while(!q.empty())    {        int k=q.front();        q.pop();        vis[k]=0;        for(int i=head[k];i!=-1;i=next[i])        {            if(dist[v[i]]>dist[k]+c[i])            {                pre[v[i]]=k;                dist[v[i]]=dist[k]+c[i];                if(!vis[v[i]])                {                    if(++cnt[v[i]]==n)                        return;                    q.push(v[i]);                    vis[v[i]]=1;                }            }        }    }    return;}void spfa2(int st){    for(int i=0;i<=n;i++)    {        dist[i]=inf;    }    dist[st]=0;    q.push(st);    while(!q.empty())    {        int k=q.front();        q.pop();        vis[k]=0;        for(int i=head[k];i!=-1;i=next[i])        {            if(dist[u[i]]>dist[k]+c[i])            {                pre[u[i]]=k;                dist[u[i]]=dist[k]+c[i];                if(!vis[u[i]])                {                    if(++cnt[u[i]]==n)                        return;                    q.push(u[i]);                    vis[u[i]]=1;                }            }        }    }    return;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        e=0;        memset(vis,0,sizeof(vis));        memset(cnt,0,sizeof(cnt));        memset(head,-1,sizeof(head));        memset(pre,-1,sizeof(pre));        scanf("%d%d",&n,&m);        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&u[i],&v[i],&c[i]);            addage(u[i],v[i],c[i]);        }        LL sum=0;        spfa1(1);        for(int i=2;i<=n;i++)        {            sum+=dist[i];        }        //printf("%d\n",sum);        turn();        memset(vis,0,sizeof(vis));        memset(cnt,0,sizeof(cnt));        spfa2(1);        for(int i=2;i<=n;i++)        {            sum+=dist[i];        }        printf("%lld\n",sum);    }    return 0;}

0 0
原创粉丝点击