一开始重新建图搞的。然后参照了别人的博客。这个解法比较好
利用在SPFA维护入队次数。入队次数大于节点数目的位于负环。
那么负环中的点如何DFS到终点。(SPFA从起点开始如果能找到入队大于N那么一定可以从起点到这个点)那么就NOBOUND;
VOID和输出ANS就比较容易了
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <climits> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define PI 3.1415926535897932626 using namespace std; int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);} #define MAXN 2000 #define MAXM 20010 const int INF = 0x3f3f3f3f; int N,M,A,B; struct node { int u,v,next; int length,weight; }edge[MAXM]; int head[MAXN],cnt; int num[MAXN],d[MAXN],l[MAXN]; bool inq[MAXN],used[MAXN]; int q[MAXM]; bool found; void insert(int u ,int v,int weight,int length) { if (head[u] != -1 && weight > edge[head[u]].weight) return; if (head[u] != -1 && weight < edge[head[u]].weight) head[u] = -1; edge[cnt].u = u; edge[cnt].v = v; edge[cnt].weight = weight; edge[cnt].length = length; edge[cnt].next = head[u]; head[u] = cnt++; } void read() { memset(head,-1,sizeof(head)); cnt = 0; for (int i = 0 ; i < M; i++) { int u ,v, weightl,weightr,length; // if (i != M - 1) scanf("(%d,%d,%d[%d]%d) ",&u,&v,&weightl,&length,&weightr); // else scanf("(%d,%d,%d[%d]%d)",&u,&v,&weightl,&length,&weightr); //printf("%d %d %d %d %d ",u,v,weightl,length,weightr); insert(u,v,weightl,length); insert(v,u,weightr,length); } } bool SPFA(int s) { int front = 0,rear = 1; memset(inq,false,sizeof(inq)); memset(num,0,sizeof(num)); memset(d,0x3f,sizeof(d)); memset(l,0x3f,sizeof(l)); inq[s] = true; q[0] = s; d[s] = l[s] = 0; num[s] = 1; while (front !=rear) { int u = q[front] ; front = (front + 1) % MAXM; inq[u] = false; for (int i = head[u]; i != -1 ; i = edge[i].next) { int v = edge[i].v; if (d[v] > d[u] + edge[i].weight ||( (d[v] == d[u] + edge[i].weight) && (l[v] > l[u] + edge[i].length))) { d[v] = d[u] + edge[i].weight; l[v] = l[u] + edge[i].length; if (!inq[v]) { inq[v] = true; num[v]++; q[rear] = v; rear = (rear + 1) % MAXM; if (num[v] > N + 4) return false; } } } } return true; } void dfs(int cur) { used[cur] = true; if (cur == B) {found = true; return;} for (int i = head[cur]; i != -1; i = edge[i].next) { int v = edge[i].v; if (!used[v]) dfs(v); } } int main() { // freopen("sample.txt","r",stdin); while (scanf("%d%d%d%d ",&N,&M,&A,&B) != EOF) { found = false; read(); bool flag = SPFA(A); if (d[B] == INF) puts("VOID"); else { if (flag) printf("%d %d ",d[B],l[B]); else { for (int i = 0 ; i < N; i++) if (num[i] > N) { memset(used,false,sizeof(used)); found = false; dfs(i); if (found) break; } if (found || num[B] > N) puts("UNBOUND"); else printf("%d %d ",d[B],l[B]); } } } return 0; }