uva 10557 - XYZZY 关键词:正环,无敌bfs,单源最短路spfa算法
2012-01-26 17:32
323 查看
笔者用时:4h。
方法一:当发现有个和为正值的环存在时,直接求看该点能否直接到达终点。如果可以,直接返回true,即winnable。否则,不用做任何的标记。因为不会再去探索它是否可以直接到达终点。这个方法效率很高。rank:7。在搜索的过程中看看有没有正环,没有正环则继续搜索,当发现所有路径都不能到达终点时,返回假值。
方法二:要低效一点。rank:300左右。用的spfa。
用最后一组给的样例,能量值改变情况如下表。通过不断地进行松弛操作,使得存在回路的点对应的能量值不断变大变大,直到可以过五关斩六将,到达终点能量依然大于0为止。或者是能量不断变大的次数超过一个给定的值(这个值要很大很大,评测数据说了算),这时认为可能因为根本就到达不了终点,或加能量、减能量疲劳而死,返回假值。
一:
#include<stdio.h> #include<string.h> #include<stdlib.h> const int maxn=100; int V[maxn],n; bool vis[maxn],G[maxn][maxn]; int q[maxn],E[maxn]; bool bfs(int u) { int front,rear; front=rear=0; memset(vis,0,sizeof(vis)); vis[u]=true; q[rear++]=u; while(front<rear) { int u=q[front++]; for(int i=0;i<n;i++) if(G[u][i] && !vis[i]) { if(i==n-1) return true; q[rear++]=i; vis[i]=true; } } return false; } bool dfs(int u,int e) { if(u==n-1) return true; for(int i=0;i<n;i++) if(G[u][i] && e+V[i]>0) { if(!E[i]) { E[i]=e+V[i]; if(dfs(i,E[i])) return true; } else if(e+V[i]>E[i] && bfs(i)) return true; } return false; } int main() { #ifndef ONLINE_JUDGE freopen("10557.txt","r",stdin); #endif while(scanf("%d",&n)==1 && n!=-1) { memset(G,0,sizeof(G)); int i,j,k; for(i=0;i<n;i++) { scanf("%d%d",&V[i],&k); for(j=0;j<k;j++) { int t; scanf("%d",&t); G[i][t-1]=true; } } memset(E,0,sizeof(E)); printf("%s\n",dfs(0,100)?"winnable":"hopeless"); } return 0; }
方法二:
#include<stdio.h> #include<string.h> #include<stdlib.h> #define INF 500000 const int maxn=100; int V[maxn],n,q[maxn],E[maxn]; bool vis[maxn],G[maxn][maxn]; bool spfa() { int front,rear; front=rear=0; memset(vis,0,sizeof(vis)); vis[0]=true; E[0]=100; q[rear++]=0; int cnt=0; while(front!=rear) { int u=q[front]; ++front%=maxn; //printf("u=%d\n",u); for(int i=0;i<n;i++) if(G[u][i] && E[i]<E[u]+V[i]) { E[i]=E[u]+V[i]; if(!vis[i]) { q[rear]=i; ++rear%=maxn; vis[i]=true; cnt++; } } if(E[n-1]>0) return true; else if(cnt>INF) return false; vis[u]=false; } return false; } int main() { #ifndef ONLINE_JUDGE freopen("10557.txt","r",stdin); #endif while(scanf("%d",&n)==1 && n!=-1) { memset(G,0,sizeof(G)); int i,j,k; for(i=0;i<n;i++) { scanf("%d%d",&V[i],&k); for(j=0;j<k;j++) { int t; scanf("%d",&t); G[i][t-1]=true; } } memset(E,0,sizeof(E)); printf("%s\n",spfa()?"winnable":"hopeless"); } return 0; }
相关文章推荐
- UVA 10557 XYZZY(DFS+BFS 与 SPFA 两种做法)
- Uva 10557 - XYZZY(DFS+BFS)
- XYZZY uva 10557 -BFS+DFS判断
- UVA - 10557 XYZZY(DFS + BFS)
- uva10557 - XYZZY(图的bfs ;dfs)
- uva 10557 XYZZY(DFS+BFS)
- uva10557 XYZZY
- UVA 11367 Full Tank?(bfs最短路)
- UVa 10557 & HDU 1317 - XYZZY
- UVA10557-XYZZY
- uva 532 Dungeon Master —— BFS(求最短路)
- HDU-1548 A strange lift(单源最短路 或 BFS)
- uva11624 fire bfs 最短路
- uva1600(最短路 bfs & dfs)
- 求单源最短路的SPFA算法
- CSU 1333 & Uva 12661 Funny Car Racing【最短路变形+spfa算法,链式前向星建图】
- 图论求单源最短路 spfa算法(附模板)
- UVALive7015(bfs求最短路)
- 用scheme语言实现SPFA算法(单源最短路)
- UVA 10557 XYZZY 结题报告