您的位置:首页 > 其它

poj 1511 Invitation Cards(2遍spfa)

2015-07-30 16:40 288 查看
题目地址

题目大意:n个站,告诉站之间的权值,求从1到所有点并返回1的最小权值和

解题思路:对1进行单源spfa,返回的时候因为spfa只能单源,所以将原图转置,再对1进行一次spfa,图的转置需要特殊处理,我采用的是邻接表存储图,相当于建了2个图

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>

using namespace std;

const int maxn = 1000000+10;
const int INF = 0xfffffff;

int dis[maxn],head[maxn],vis[maxn],cnt,n,m;
int u[maxn],v[maxn],w[maxn];

struct Edge
{
int to,next,w;
}e[maxn];

void addEdge(int u,int v,int w)
{
e[cnt].to = v;
e[cnt].w = w;
e[cnt].next = head;
head[u] = cnt++;
}

void spfa()
{
queue<int> q;
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i++)
dis[i] = INF;
q.push(1);
vis[1] = 1;
dis[1] = 0;
while(!q.empty())
{
int v = q.front();
q.pop();
vis[v] = 0;
for(int i = head[v]; i != -1; i = e[i].next)
{
if(dis[e[i].to] > dis[v]+e[i].w)
{
dis[e[i].to] = dis[v]+e[i].w;
if(!vis[e[i].to])
{
vis[e[i].to] = 1;
q.push(e[i].to);
}
}
}
}
}

void graph1()
{
cnt = 1;
memset(head,-1,sizeof(head));
for(int i = 1; i <= m; i++)
addEdge(u[i],v[i],w[i]);
}

void graph2()
{
cnt = 1;
memset(head,-1,sizeof(head));
for(int i = 1; i <= m; i++)
addEdge(v[i],u[i],w[i]);
}

int main()
{
int t,sum;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
}
sum = 0;
graph1();
spfa();
for(int i = 2; i <= n; i++)
sum += dis[i];
graph2();
spfa();
for(int i = 2; i <= n; i++)
sum += dis[i];
printf("%d\n",sum);
}
return 0;
}


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