点击打开链接hdu 1224
思路:最短路+SOFA
分析:
1 提要要求的最大的环,蛋并不是这么的复杂,因为第一个点的points值为0,所以其实就是求1到某一个点的最长路,其实就是最长路问题
2 注意的是在求1到某一个点的最长路的时候还要注意这个点是否能够到达1点,这个可以用一个mark数组来标记
3 可以更简单的做法就是1-n+1的最长路。
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> using namespace std; #define MAXN 110 #define INF 0xFFFFFFF int t , n , m; int num[MAXN]; int path[MAXN]; int father[MAXN]; int value[MAXN][MAXN]; int dis[MAXN]; int mark[MAXN]; int vis[MAXN]; queue<int>q; void SPFA(){ memset(vis , 0 , sizeof(vis)); memset(dis , 0 , sizeof(dis)); memset(num , 0 , sizeof(num)); father[1] = father[n] = 1; vis[1] = 1; q.push(1); while(!q.empty()){ int x = q.front(); q.pop(); vis[x] = 0; for(int i = 1 ; i <= n ; i++){ if(value[x][i] && dis[i] < dis[x] + value[x][i]){ dis[i] = dis[x] + value[x][i]; father[i] = x; if(!vis[i]){ vis[i] = 1; q.push(i); } } } } } int main(){ int i , j , a , b , cnt; int pos , ans; scanf("%d" , &t); for(i = 1 ; i <= t ; i++){ /*输入n个城市的points*/ scanf("%d" , &n); memset(value , 0 , sizeof(value)); memset(mark , 0 , sizeof(mark));/*标记为0*/ for(j = 1 ; j <= n ; j++) scanf("%d" , &num[j]); /*输入边的关系*/ scanf("%d" , &m); for(j = 0 ; j < m ; j++){ scanf("%d%d" , &a , &b); if(b == n+1){ mark[a] = 1; continue; } value[a][b] = num[b]; } /*求SPFA*/ SPFA(); /*求最大值的点*/ ans = 0; pos = 1; for(j = 2 ; j <= n ; j++){ if(mark[j] && ans < dis[j]){ ans = dis[j]; pos = j; } } /*求路径path*/ a = pos; cnt = 0; memset(path , 0 , sizeof(path)); path[cnt++] = pos; while(1){ b = father[a]; if(b == 1) break; path[cnt++] = b; a = b; } /*输出*/ printf("CASE %d#\n" , i); printf("points : %d\n" , ans); printf("circuit : 1"); for(j = cnt-1 ; j >= 0 ; j--) printf("->%d" , path[j]); printf("->1\n"); if(i < t) printf("\n"); } return 0; }