zoj 2008 && poj 1511 Invitation Cards

来源:互联网 发布:淘宝名忘了怎么找回 编辑:程序博客网 时间:2024/06/06 19:34

题意:在有向图中求起点到所有点的最短路径长度和所有点到起点的最短路径长度的总和。


思路:

1.起点到所有点的最短路径很好求,直接求单源最短路径即可。

2.所有点到起点的最短路径,如果我们把每一条边都反过来,那么再求一次单源最短路径即可。


注意:

1.poj上的数据超int了,需要用long long。

2.我用cin超时了。。。,换scanf就过了,唉cin还是少用啊。

3.poj 6000ms有点慢。。。


代码:


#include <iostream> #include <cstdio>#include <vector>#include <queue>using namespace std;const long long inf = 1000000000005;const int maxn = 1000005;struct node{int index;int w;node(int tindex, int tw){index = tindex; w = tw;}bool operator < (const node &b) const{return w > b.w;}};struct edge{int v;int w;edge(int tv, int tw){v = tv; w = tw;}};int n,m;int x[maxn],y[maxn],wi[maxn];long long dist[maxn];//Dijkstra算法所需的数组 bool vis[maxn];vector<edge> a[maxn]; //邻接矩阵priority_queue<node> q;void Input() {int u,v,w;scanf("%d%d",&n,&m);for(int i = 1; i <= m; i++){scanf("%d%d%d",&x[i],&y[i],&wi[i]);}}void Dijkstra(){for(int i = 1; i <= n; i++){vis[i] = 0;dist[i] = inf;}dist[1] = 0;q.push(node(1,0));//初始节点入队 while(!q.empty()){int u = q.top().index;q.pop(); if(vis[u]) continue;else vis[u] = 1;for(int j = 0; j < a[u].size(); j++){int v = a[u][j].v;if(!vis[v] && dist[u] + a[u][j].w < dist[v]){dist[v] = dist[u] + a[u][j].w;q.push(node(v,dist[v]));}}}}void Solve(){long long sum = 0;for(int i = 1; i <= n; i++) a[i].clear();for(int i = 1; i <= m; i++) a[x[i]].push_back(edge(y[i],wi[i]));Dijkstra();for(int i = 1; i <= n; i++){sum += dist[i];}for(int i = 1; i <= n; i++) a[i].clear();for(int i = 1; i <= m; i++) a[y[i]].push_back(edge(x[i],wi[i]));Dijkstra();for(int i = 1; i <= n; i++){sum += dist[i];}printf("%lld\n",sum);}int main(){int t;cin>>t;while(t--){Input();Solve();}}

0 0