uva11721 Instant View of Big Bang

来源:互联网 发布:安全炒股软件 编辑:程序博客网 时间:2024/05/16 23:33

题意:大意就是有很多虫洞,他们之间存在有向通道,可能把时间提前,也可能往后,,,一个科学家想要回到很早很早之前,,,问从那些冲动出发可以满足条件。显然要回到很久以前必然要到达某个负环,首先要找到负环,然后再找哪些冲动可以到达这个负环,,,这题最大的难点就是建图,对于负环而言,无论是反向建边还是正向建边,,这个不影响,,,如果反向建边,,,,那么就可以从找点到负环变成了负环可达的问题了,,,这样一来,,,发现负环后,,,就把这个可达的所有点标记起来,,,这就是最后的答案。。。

// #pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <algorithm>#include <iomanip>#include <sstream>#include <string>#include <stack>#include <queue>#include <deque>#include <vector>#include <map>#include <set>#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#include <limits.h>// #define DEBUG#ifdef DEBUG#define debug(...) printf( __VA_ARGS__ )#else#define debug(...)#endif#define MEM(x,y) memset(x, y,sizeof x)using namespace std;typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> ii;const int inf = 1 << 30;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;const int maxn = 1010;int head[maxn], pnt[maxn<<2], nxt[maxn<<2], cost[maxn<<2];int n, m;int in[maxn], dis[maxn];bool mark[maxn];bool vis[maxn];bool flag;void dfs(int u){vis[u] = true;for (int i = head[u];i != -1;i = nxt[i]){int v = pnt[i];if (!vis[v]) dfs(v);}}void spfa(int st){queue<int> que;que.push(st);memset(dis, INF,sizeof dis);memset(mark, false,sizeof mark);memset(in, 0,sizeof in);dis[st] = 0;while(!que.empty()){int u = que.front();que.pop();mark[u] = false;for (int i = head[u];i != -1;i = nxt[i]){int v = pnt[i];int w = cost[i];if (vis[v]) continue;if (dis[v] > dis[u] + w){dis[v] = dis[u] + w;if (!mark[v]){in[v]++;if (in[v] > n){flag = true;dfs(v);continue;}mark[v] = true;que.push(v);}}}}}int cnt;void add(int u,int v,int w){pnt[cnt] = v;nxt[cnt] = head[u];cost[cnt] = w;head[u] = cnt++;}int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);int t, icase = 0;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);memset(head, -1,sizeof head);cnt = 0;for (int i = 0,a,b,c;i < m;++i){scanf("%d%d%d",&a,&b,&c);add(b,a,c);}flag = false;memset(vis, false,sizeof vis);printf("Case %d:",++icase);for (int i = 0;i < n;++i)if (!vis[i]) spfa(i);if (!flag) {printf(" impossible\n");continue;}for (int i = 0;i < n;++i){if (vis[i]) printf(" %d",i);}printf("\n");}return 0;}


0 0