Problem
对于一个n个顶点的有向强连通图,求.
Solution
对于,可以用spfa或dijstra求出单源最短路,对于,可以将边反向后求最短路。
本人用的是spfa,要注意手搓循环队列的时候,不是front < rear,而是front != rear,偷偷告诉你我不太会写dijstra
同时,最好不写双份代码,不便于调试。
Code
#include<cstdio>
#include<cstring>
#define MAXN 1005
#define MAXM 100010
#define INF 999999999
using namespace std;
int read(){
int res = 0, ch = getchar();
bool flag = false;
while((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if(ch == '-'){
flag = true;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
res = (res << 3) + (res << 1) + (ch - '0');
ch = getchar();
}
return flag ? -res : res;
}
void write(int x){
if(x < 0){
putchar('-');
x = -x;
}
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
struct Graph {
int n, cnt, head[MAXN], nxt[MAXM], to[MAXM], w[MAXM], dis[MAXN];
void add_edge(int a, int b, int c){
to[++ cnt] = b;
w[cnt] = c;
nxt[cnt] = head[a];
head[a] = cnt;
}
void spfa(int k){
static int que[MAXN];
static bool inq[MAXN];
int front = 0, rear = 1;
memset(inq, false, sizeof inq);
for(int i = 1;i <= n;i ++)
dis[i] = (i == k) ? 0 : INF;
que[front] = k;
inq[k] = true;
while(front != rear){
int cur = que[front];
front = (front + 1) % MAXN;
inq[cur] = false;
for(register int i = head[cur];i;i = nxt[i])
if(dis[to[i]] > dis[cur] + w[i]){
dis[to[i]] = dis[cur] + w[i];
if(!inq[to[i]]){
que[rear] = to[i];
rear = (rear + 1) % MAXN;
inq[to[i]] = true;
}
}
}
}
} gra1, gra2;
int main(){
gra1.n = gra2.n = read();
int m = read(), ans = 0;
for(register int i = 0;i < m;i ++){
int a = read(), b = read(), c = read();
gra1.add_edge(a, b, c);
gra2.add_edge(b, a, c);
}
gra1.spfa(1);
gra2.spfa(1);
for(register int i = 2;i <= gra1.n;i ++)
ans += gra1.dis[i] + gra2.dis[i];
write(ans);
}