poj1511

来源:互联网 发布:access数据库安装包 编辑:程序博客网 时间:2024/05/30 23:17

Problem: Invitation Cards

Description: 在一个城市里,有n(1~1000000)个运输中心,有m条有向路连接着任意的两个运输中心。ACM组织(位于编号为1的运输中心)要派发p个雇佣员工早上前往这p个运输中心去发传单,晚上再让他们都回到组织中。问所有人所走路程的总和最短是多少?

Solution: 这是个最短路的问题,先一次用SPFA求早上从顶点1到各点的最短路径,再对其反向图,用SPFA求从顶点1到各点的最短路径,这个值就是晚上各点回到顶点1的值,两个值相加就是所求。第一次用SPFA,参考了http://www.360doc.com/content/13/1208/22/14357424_335569176.shtml讲解的SPFA算法。做这个题我也深刻地感受到了scanf输入比cin要快,开始用cin输入TLE,后来改成scanf,2297MS过了,快了不止一点点啊。

Code(C++):

#include <iostream>#include <cstring>#include <cstdio>#include <queue>#define N  1005000#define inf 0x3f3f3f3fusing namespace std;struct Edge{    int u;    int v;    long long c;    int next;} p[N];int head[N];long long dis[N];int visit[N];int T,m,n,e;void addnode(int u,int v,long long c){    p[e].u=u;    p[e].v=v;    p[e].c=c;    p[e].next=head[u];    head[u]=e;    e++;}void init(){    memset(head,-1,sizeof(head));    for(int i=1;i<N;i++)        p[i].next=-1;    e=0;    int u,v;    long long c;    for(int i=0; i<n; i++)    {        scanf("%d%d%lld",&u,&v,&c);        addnode(u,v,c);    }}void reinit(){    memset(head,-1,sizeof(head));    for(int i=1;i<=N;i++)        p[i].next=-1;    e=0;    for(int i=0;i<n;i++)    {        addnode(p[i].v,p[i].u,p[i].c);    }}int Spfa(int src){    int u,v,weight;    memset(visit,0,sizeof(visit));    memset(dis,inf,sizeof(dis));    dis[src]=0;    queue<int>q;    while(!q.empty())        q.pop();    q.push(src);    visit[src]=1;    while(!q.empty())    {        u=q.front();        q.pop();        visit[u]=0;        for(int i=head[u]; i!=-1; i=p[i].next)        {            v=p[i].v;            weight=p[i].c;            if(dis[v]>dis[u]+weight)            {                dis[v]=dis[u]+weight;                if(!visit[v])                {                    q.push(v);                    visit[v]=1;                }            }        }    }}int main(){    scanf("%d",&T);    while(T--)    {        long long sum1=0,sum2=0,sum;        scanf("%d%d",&m,&n);        init();        Spfa(1);        for(int i=1;i<=m;i++)            sum1+=dis[i];        reinit();        Spfa(1);        for(int i=1;i<=m;i++)            sum2+=dis[i];        sum=sum1+sum2;        cout<<sum<<endl;    }    return 0;}
0 0