您的位置:首页 > 其它

poj 1511 -- Invitation Cards

2013-11-18 14:03 204 查看
/*
n个顶点,m条有向边
求出源点1到其他顶点的最短距离跟其他顶点到源点的最短距离之和
数据量比较到。用的邻接表存储的spfa
还有一点要注意的是dis[] 跟 ans要用__int64,
都是数据量大的原因。
这里用的是stack的spfa
*/
#include<iostream>
#include<stdio.h>
#include<stack>
#include<string.h>
using namespace std;
const int N = 1000010;
const int inf = 0x3f3f3f3f;
int head
;

int outstack
;

bool vis
;

__int64 dis
;

int n,m,num_edge;

typedef struct
{
int end,w,nxt;
} Edge;

Edge edge
;

typedef struct
{
int start,end,w;
} Node;

Node data
;

void addedge(int start,int end,int w)
{
edge[num_edge].end = end;
edge[num_edge].w = w;
edge[num_edge].nxt = head[start];
head[start]= num_edge++;
}

bool spfa(int start)
{
for(int i = 1 ; i <= n ; i++)
{
dis[i] = inf;
outstack[i] = 0;
vis[i] = false;
}
stack<int>s;
s.push(start);
vis[start] = true;
dis[start] = 0;
while(!s.empty())
{
int cur = s.top();
s.pop();
outstack[cur]++;
if(outstack[cur] > n)
{
return false;
}
for(int i = head[cur] ; i != -1 ; i = edge[i].nxt)
{
int x = edge[i].end;
if(dis[x] > dis[cur] + edge[i].w)
{
dis[x] = dis[cur] + edge[i].w;
if(!vis[x])
{
vis[x] = true;
s.push(x);
}
}
}
vis[cur] = false;
}
return true;
}

int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d %d",&n,&m);
num_edge = 0;
for(int i = 0 ; i <= n ; i++)
{
head[i] = -1;
}
for(int i = 0 ; i < m ; i++)
{
scanf("%d %d %d",&data[i].start,&data[i].end,&data[i].w);
addedge(data[i].start,data[i].end,data[i].w);
}
spfa(1);
__int64 ans = 0;
for(int i = 1 ; i <= n ; i++)
{
ans += dis[i];
}
num_edge = 0;
for(int i = 0 ; i <= n ; i++)
{
head[i] = -1;
}
for(int i = 0 ; i < m ; i++)
{
addedge(data[i].end,data[i].start,data[i].w);
}
spfa(1);
for(int i = 1 ; i <= n ; i++)
{
ans += dis[i];
}
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: