USACO 4.1 Fence Loops(无向图中的最小环)
2013-02-20 17:16
274 查看
这个算是一个模版题,不过以前没见过。。。我冥思苦想,想爆搜,却知从何搜起,然后突然想到以前做过一个最小环的,关于某一个点的最小环两遍spfa,搞定。然后我啪啪开写,先自己把数据转化为点,然后离散一下。。。写了老长,还选择比较好写的floyd,样例过不了,意识到发现这样写不对啊。。。
从网上找到了做法。。
1:朴素的求最小环的方法做E遍Dijkstra,枚举每条边e(i,j),删去边e(i,j)之后,求i到j的最短路经,然后再加上该边求最小值便得到的了最小环,时间复杂度为O(E*(N^2))。
2:改进的floyd算法,求出任意两点之间的最短路的同时,求出最小环。
我用的是后者,因为图都建好了。。。不能白写了啊。。。证明详细,还是去搜网上的资料把。
从网上找到了做法。。
1:朴素的求最小环的方法做E遍Dijkstra,枚举每条边e(i,j),删去边e(i,j)之后,求i到j的最短路经,然后再加上该边求最小值便得到的了最小环,时间复杂度为O(E*(N^2))。
2:改进的floyd算法,求出任意两点之间的最短路的同时,求出最小环。
我用的是后者,因为图都建好了。。。不能白写了啊。。。证明详细,还是去搜网上的资料把。
/* ID: cuizhe LANG: C++ TASK: fence6 */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map> #include <string> #include <vector> using namespace std; #define N 10000000 int o[301]; int dp[201][201],g[201][201]; struct point { int x,y,dis; int nl,nr; int L[9],R[9]; } p[101]; int pfind(int x,int key) { int i; for(i = 1; i <= p[key].nl; i ++) { if(p[key].L[i] == x) return p[key].x; } for(i = 1; i <= p[key].nr; i ++) { if(p[key].R[i] == x) return p[key].y; } return 200; } int build(int n)//建图 { int i,j,r,c,num; for(i = 1; i <= n; i ++) { o[p[i].x] = 1; o[p[i].y] = 1; } num = 1; for(i = 1; i <= 2*n; i ++) { if(o[i]) o[i] = num ++; } for(i = 1; i <= num-1; i ++) { for(j = 1; j <= num-1; j ++) { g[i][j] = dp[i][j] = N; } g[i][j] = dp[i][i] = 0; } for(i = 1; i <= n; i ++) { if(o[p[i].x] > o[p[i].y]) { r = o[p[i].x]; c = o[p[i].y]; } else { c = o[p[i].x]; r = o[p[i].y]; } g[r][c] = dp[r][c] = min(dp[r][c],p[i].dis); g[c][r] = dp[c][r] = min(dp[c][r],p[i].dis); } return num-1; } int main() { int i,j,n,num,k,minz; freopen("fence6.in","r",stdin); freopen("fence6.out","w",stdout); scanf("%d",&n); for(i = 1; i <= n; i ++) { p[i].x = 2*i-1; p[i].y = 2*i; } for(i = 1; i <= n; i ++) { scanf("%d",&num); scanf("%d%d%d",&p[num].dis,&p[num].nl,&p[num].nr); for(j = 1; j <= p[num].nl; j ++) scanf("%d",&p[num].L[j]); for(j = 1; j <= p[num].nr; j ++) scanf("%d",&p[num].R[j]); } for(i = 1; i <= n; i ++) { for(j = 1; j <= p[i].nl; j ++) { p[i].x = min(p[i].x,pfind(i,p[i].L[j])); } for(j = 1; j <= p[num].nr; j ++) { p[i].y = min(p[i].y,pfind(i,p[i].R[j])); } } n = build(n); minz = N; for(i = 1; i <= n; i ++)//求最小环 { for(j = 1; j <= i-1; j ++) for(k = j+1; k <= i-1; k ++) minz = min(minz,dp[j][k] + g[j][i] + g[i][k]); for(j = 1; j <= n; j ++) for(k = 1; k <= n; k ++) dp[j][k] = min(dp[j][k],dp[j][i]+dp[i][k]); } printf("%d\n",minz); return 0; }
相关文章推荐
- usaco 4.1 Fence Loops(floyd求最小环)
- usaco 4.1 Fence Loops 最小环
- USACO 4.1 Fence Loops (fence6)
- USACO 4.1 Fence Loops
- USACO 4.1 Fence Loops 最小环
- USACO 4.1 Fence Loops(Floyd求最小环)
- 第四章 4.1无向图
- usaco-4.1-fence6-passed
- [USACO4.1.2]Fence Loops
- usaco 4.1.3 Fence Loops (floyd)做法
- USACO-Section 4.1 Beef McNuggets (DP)
- USACO 4.1 Beef McNuggets
- [USACO4.1]麦香牛块Beef McNuggets
- USACO 4.1 Beef McNuggets
- USACO 4.1 Beef McNuggets(DP)
- Fence Loops[USACO]
- usaco 4.1 Cryptcowgraphy
- [USACO4.1]麦香牛块Beef McNuggets 题解报告
- usaco4.1.2 Fence Loops
- HDU 1599 find the mincost route (无向图的最小环)