UVA 558 Wormholes

来源:互联网 发布:linux权限命令 编辑:程序博客网 时间:2024/05/05 08:23

要问是否存在一个总权重为负数的环,用dfs即可解决。

 time:33ms

 1 #include <cstdio> 2 #include <cstring> 3 #define N 3000 4 using namespace std; 5 int n, m, T, w[N], u[N], v[N], next[N], first[N], pa[N], d[N], tag, i; 6  7 void read_graph(void) 8 { 9     for(int e = 0; e < m; e++)10     {11         scanf("%d%d%d",&u[e], &v[e], &w[e]);12         next[e] = first[u[e]];13         first[u[e]] = e;14     }15 }16 void dfs(int x, int fa, int dis)17 {18     pa[x] = fa;19     d[x] = dis;20     for(int e = first[x]; e != -1; e = next[e])21         if(tag) return;22         else if(pa[v[e]] == -1)//这里应该改为pa[v[e]] != x ,要考虑到负权上的点可能事先被访问过,感谢提出 23         {24             if(v[e] == i && d[x] + w[e] <  0)25             {26                 puts("possible"), tag = 1;27                 return ;28             }29             if(v[e] == i)30                 continue;31             dfs(v[e], x, d[x] + w[e]);32         }33 }34 int main(void)35 {36     scanf("%d", &T);37     while(T--)38     {39         memset(first, -1, sizeof(first));40         tag = 0;41         scanf("%d%d", &n, &m);42         read_graph();43         for(i = 0; i < n; i++)44         {45             memset(d, 0, sizeof(d)), memset(pa, -1, sizeof(pa)),46                    dfs(i, -1, 0);47                    if(tag)48                     break;49         }50         if(!tag)51             puts("not possible");52     }53     return 0;54 }

 或者采用bellman—ford算法判断负权回路,

第n次循环时,若d[y]>d[x] + w[i],也就是能够继续松弛下去说明图中存在负权回路。

time:44ms速度还慢了一点,相比dfs

 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #define INF 0x0f0f0f0f 6 #define MAXN 1111 7 #define MAXM 2222 8 using namespace std; 9 10 int d[MAXN];11 int u[MAXM], v[MAXM], w[MAXM], next[MAXM], first[MAXM];12 int t, n, m, e;13 void read_graph(void)14 {15     scanf("%d%d",&n, &m);16     for(e = 0; e < m; e++)17     {18         scanf("%d%d%d",&u[e], &v[e], &w[e]);19         next[e] = first[u[e]];20         first[u[e]] = e;21     }22 }23 void bellman_ford(void)24 {25     int i;26     for(int k = 0; k < n-1; k++)27         for(i = 0; i < e; i++ )28     {29         int x = u[i], y = v[i];30         if(d[x] < INF)31             d[y] = min(d[y], d[x] + w[i]);32     }33     for(i = 0; i < e; i++)34     {35         int x = u[i], y = v[i];36         if(d[y] > d[x] + w[i])37         {38             puts("possible");39             break;40         }41     }42     if(i == e)43         puts("not possible");44 }45 int main(void)46 {47     scanf("%d",&t);48     while(t--)49     {50         memset(d, 0x0f, sizeof(d));51         memset(first, -1, sizeof(first));52         d[0] = 0;53         read_graph();54         bellman_ford();55     }56     return 0;57 }

 然后是spfa算法求解是否存在负权回路,通过判断顶点出队次数大于顶点数n,可知存在负权路,源点的time[0]应该初始化为1,其他的点每松弛一次,次数增加。

time:77ms竟然比bellman—ford,自己写的dfs倒是成了最快的了。

 

 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <vector> 5 #define MAXN 1111 6 #define MAXM 2222 7 using namespace std; 8  9 struct edgeType{10 int v, w;11 edgeType(int a, int b):v(a), w(b){}12 };13 int n,m,t;14 int time[MAXN], inq[MAXN], d[MAXN];15 16 vector <edgeType> g[MAXN];17 18 bool spfa(void)19 {20     queue <int> q;21     time[0] = 1;22     q.push(0);23     inq[0] = 1;24     while(!q.empty())25     {26         int x = q.front();27         q.pop();28         inq[x] = 0;29         for(int i = 0; i < (int)g[x].size(); i++)30             if(d[g[x][i].v] > d[x] + g[x][i].w)31             {32                 d[g[x][i].v] = d[x] + g[x][i].w;33                 time[g[x][i].v]++;34                 if(time[g[x][i].v] == n + 1)35                     return false;36                 if(!inq[g[x][i].v])37                 {38                     q.push(g[x][i].v);39                     inq[g[x][i].v] = 1;40                 }41             }42     }43     return true;44 }45 int main(void)46 {47     scanf("%d", &t);48     while(t--)49     {50         scanf("%d%d", &n, &m);51         int a, b, c;52         memset(time, 0, sizeof(time));53         memset(inq, 0,sizeof(inq));54         memset(d, 0x0f,sizeof(d));55         d[0] = 0;56          for(int i = 0; i < MAXN; i++)57             g[i].clear();58         for(int i = 0; i < m;i++)59         {60             scanf("%d%d%d", &a, &b, &c);61             g[a].push_back(edgeType(b, c));62         }63         if(spfa())64             puts("not possible");65         else puts("possible");66     }67     return 0;68 }

 

                                                                 

0 0
原创粉丝点击