POJ 1511 Invitation Cards (最短路的两种方法spfa, Dij)
题意:
给定n个点, m条路, 求1到 2 ~n的最短路之和加上2~n到1的最短路之和
分析:
裸最短路, 求其他点到源点的距离只需要把边方向再从源点求一次即可
spfa代码
#include<iostream> #include<vector> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<cstdlib> #include<ctime> #include<queue> #include<set> #include<map> #include<stack> #include<bitset> #define rep(i,a,b) for(int i = a; i < b; i++) #define _rep(i,a,b) for(int i = a; i <= b; i++) #define mem(a,n) memset(a,n,sizeof(a)) #define fre(a) freopen(a,"r", stdin); typedef long long LL; using namespace std; const LL inf = 1e12 + 7; const int maxn = 1e6 + 7; inline void read(int &x) { int k=0; char f=1; char c=getchar(); while(c>'9'||c<'0') if(c=='-') { f=-1; c=getchar(); } while(c<='9'&&c>='0') { k=k*10+c-'0'; c=getchar(); } x = k*f; } struct edge { LL to, d; edge(LL _to, LL _d):to(_to), d(_d) {} }; struct { int to, next, d; } node[2][maxn]; int head[2][maxn]; int cnt; int n, m; LL ans; LL dis[maxn]; bool vis[maxn]; void dij(int st, int index) { fill(dis, dis+n+1, inf); mem(vis,0); dis[st] = 0; vis[st] = 1;//记得入队标记第一个点 queue<int> q; q.push(1); while(!q.empty()) { int u = q.front(); for(int i = head[index][u]; i != -1; i = node[index][i].next) { int v = node[index][i].to; if(!vis[v] && dis[u] + node[index][i].d < dis[v]) { dis[v] = dis[u] + node[index][i].d; if(!vis[v]) q.push(v);//松弛后如果没有在队中就入队 } } q.pop(); vis[u] = 0; } LL sum = 0; _rep(i,2,n) ans += dis[i]; } int main() { int T; read(T); while(T--) { cnt = 0; ans = 0; mem(head[0],-1); mem(head[1],-1); read(n), read(m); rep(i,0,m) { int u, v, d; read(u) , read(v) , read(d) , node[0][cnt].to = v; node[0][cnt].d = d; node[0][cnt].next = head[0][u]; head[0][u] = cnt; node[1][cnt].to = u; node[1][cnt].d = d; node[1][cnt].next = head[1][v]; head[1][v] = cnt++; } dij(1,0); dij(1,1); printf("%lld\n", ans); } return 0; }
dijkstra代码:
#include<iostream> #include<vector> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<cstdlib> #include<ctime> #include<queue> #include<set> #include<map> #include<stack> #include<bitset> #define rep(i,a,b) for(int i = a; i < b; i++) #define _rep(i,a,b) for(int i = a; i <= b; i++) #define mem(a,n) memset(a,n,sizeof(a)) #define fre(a) freopen(a,"r", stdin); typedef long long LL; using namespace std; const LL inf = 1e12 + 7; const int maxn = 1e6 + 7; inline void read(int &x) { int k=0; char f=1; char c=getchar(); while(c>'9'||c<'0') if(c=='-') { f=-1; c=getchar(); } while(c<='9'&&c>='0') { k=k*10+c-'0'; c=getchar(); } x = k*f; } struct edge { LL to, d; edge(LL _to, LL _d):to(_to), d(_d) {} }; struct { int to, next, d; } node[2][maxn]; int head[2][maxn]; int cnt; int n, m; LL ans; LL dis[maxn]; bool vis[maxn]; void dij(int st, int index) { fill(dis, dis+n+1, inf); mem(vis,0); dis[st] = 0;//dij不需要标记第一个点 priority_queue<pair<int,int>, vector< pair<int,int> >, greater<pair<int, int> > > q;//用pair的时候要记得优先队列如果不加greater<pair<int, int>> 是按从大到小排列的 q.push(make_pair(0,1)); while(!q.empty()) { int u = q.top().second; q.pop(); if(vis[u]) continue; vis[u] = 1; for(int i = head[index][u]; i != -1; i = node[index][i].next) { int v = node[index][i].to; if(!vis[v] && dis[u] + node[index][i].d < dis[v]) { dis[v] = dis[u] + node[index][i].d; q.push(make_pair(dis[v],v)); } } } LL sum = 0; _rep(i,2,n) ans += dis[i]; } int main() { int T; read(T); while(T--) { cnt = 0; ans = 0; mem(head[0],-1); mem(head[1],-1); read(n), read(m); rep(i,0,m) { int u, v, d; read(u) , read(v) , read(d) , node[0][cnt].to = v; node[0][cnt].d = d; node[0][cnt].next = head[0][u]; head[0][u] = cnt; node[1][cnt].to = u; node[1][cnt].d = d; node[1][cnt].next = head[1][v]; head[1][v] = cnt++; } dij(1,0); dij(1,1); printf("%lld\n", ans); } return 0; }