您的位置:首页 > 其它

poj1511 spfa

2014-12-07 09:33 309 查看
如题:http://poj.org/problem?id=1511

用spfa求一个图1到各个点的最短路径,然后将图反向,再求一次,2次的结果相加。



#include<iostream>

using namespace std;

#define inf 1000000000000LL

#define MAXN 1000005

#define MAXM 1000005

struct note

{

int u,v;

long long c;

note(){}

note(int u,int v,long long c):u(u),v(v),c(c){}

};

note p[MAXM];

int head[MAXN],next[MAXM];

long long dp[MAXN];

bool map[MAXN];

int now[MAXN];

int e,top,n,m;

void addnote(int u,int v,long long c)

{

p[e]=note(u,v,c);

next[e]=head[u];

head[u]=e++;

}

void init()

{

memset(head,-1,sizeof(head[0])*(n+2));

memset(next,-1,sizeof(next[0])*(m+2));

e=0;

int i;

for(i=0;i<m;i++)

{

int u,v;

long long c;

scanf("%d%d%lld",&u,&v,&c);

addnote(u,v,c);

}

}

void uninit()

{

memset(head,-1,sizeof(head[0])*(n+2));

memset(next,-1,sizeof(next[0])*(m+2));

e=0;

int i;

for(i=0;i<m;i++)

addnote(p[i].v,p[i].u,p[i].c);

}

long long get_sum(long long a[])

{

long long res=0;

for(int i=1;i<=n;i++)

{

res+=a[i];

}

return res;

}

bool relax(int u,int v,long long c)

{

if(dp[v]>dp[u]+c)

{

dp[v]=dp[u]+c;

return true;

}

return false;

}

void spfa(int t)

{

memset(map,0,sizeof(map[0]*(n+2)));

int i;

for(i=1;i<=n;i++)

dp[i]=inf;

dp[t]=0;

map[t]=true;

top=0;

now[top++]=t;

while(top)

{

int pre=now[--top];

map[pre]=false;

int j;

for(j=head[pre];j+1;j=next[j])

{

if(relax(p[j].u,p[j].v,p[j].c)&&map[p[j].v]==false)

{

now[top++]=p[j].v;

map[p[j].v]=true;

}

}

}

}

int main()

{

//freopen("C:\\1.txt","r",stdin);

int T;

scanf("%d",&T);

while(T--)

{

scanf("%d%d",&n,&m);

init();

spfa(1);

long long ans=get_sum(dp);

uninit();

spfa(1);

ans+=get_sum(dp);

printf("%lld\n",ans);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: