poj 1511 -- Invitation Cards
来源:互联网 发布:java float精度 编辑:程序博客网 时间:2024/05/16 05:10
/* 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[N];int outstack[N];bool vis[N];__int64 dis[N];int n,m,num_edge;typedef struct{ int end,w,nxt;} Edge;Edge edge[N];typedef struct{ int start,end,w;} Node;Node data[N];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;}