UVAlive--4529--Dangerous Tunnels(二分+拆点最大流)
Posted playboy307
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVAlive--4529--Dangerous Tunnels(二分+拆点最大流)相关的知识,希望对你有一定的参考价值。
Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
Somewhere in the world, there are two tribes separated by mountains. The two tribes are named Kulolo and Gulolo, respectively, where Kulolo is at a higher altitude and Gulolo is at a lower altitude. Due to the limitation of geography, Gulolo has fewer resources
than Kulolo. In order to transport resources from Kulolo to Gulolo efficiently, several tunnels were built inside the mountains between these two tribes. There are also some rest stations built for people to take a break during the transportation in the tunnels.
More specifically, each terminal of a tunnel is either Kulolo, Gulolo, or a rest station.
The structure of those tunnels is not stable. A dangerous degree has been estimated for each tunnel, due to its stability, in advance. A tunnel with a higher dangerous degree is considered to be more dangerous; that is, it is more probably to collapse. Kinglolo, the chief of Kulolo, would like to select some paths through the tunnels to Gulolo with little risk. In Kinglolo‘s opinion, the dangerous degree of a path is equal to the maximum dangerous degree of the tunnels in the path; and the dangerous degree of a set of paths is equal to the maximum dangerous degree of the paths in it. For example, consider Figure 1. The dangerous degrees of P1, P2 , and P3 are, respectively, 3, 5, and 6. And, the dangerous degree of {P2, P3} is 6.
Since all tunnels are narrow, a limited quantity of resources can be transported along a path in one day. Therefore, every day, depending on the amount of resources needed to be transported, a different number, say k , of paths is required. Moreover, to avoid congestion, these k selected paths cannot pass any rest station in common. For example, in Figure 1, P2 and P3
People in Kulolo believe that Kinglolo is the most brilliant man in the world, since he always selects a set of k paths that is as little dangerous as possible (i.e., the maximum dangerous degree of the selected paths is minimized). Now, given the data of the constructed tunnels, you are asked to find k paths that Kinglolo may select. In summary, the k selected paths, if exist, should satisfy the following:
- all paths are from Kulolo to Gulolo,
- no two paths pass the same rest station,
- the altitudes of the rest stations on each path are non-increasing, and
- the maximum dangerous degree of the paths is minimized.
For simplicity, only the maximum dangerous degree of the selected paths should be reported.
Technical Specification
- The number of rest stations, n : 0 < n200 .
- The number of tunnels, t : t > 0 .
- The dangerous degree of a tunnel, d : 1d100000 .
- The number of paths which should be selected, k : 1k10 .
Input
The input consists of multiple test cases. The first line of each case contains a positive integer n(0 < n200) which indicates that there are n rest stations r1, r2,..., rn . For ease of description, Kulolo and Gulolo are denoted by r0 and rn+1 , respectively. We assume that ri is higher than rj for any 0i < jn + 1 . The second line of each case contains a positive integert(t > 0) that specifies the number of tunnels. Each of the following t lines contains three integers p , q , d(0pn + 1, 0qn + 1, pq, 1d100000) separated by white space, which indicate there is a tunnel with dangerous degree d connecting rp and rq . Then, a line containing a positive integer k(1k10) is provided, which is the number of paths that should be selected. You can assume that there is at most one tunnel between any two rest stations. The last test case is followed by a line containing a zero.
Output
For each test case, print a line containing the test case number (beginning with 1) followed by the maximum dangerous degree of the k paths that Kinglolo may select. If the solution does not exist, print `` no solution". Use the format of the sample output.
Sample Input
2 4 0 1 3 1 3 12 2 0 10 2 3 5 1 1 2 0 1 5 1 2 6 2 3 2 0 1 5 3 4 7 1 3 6 0 1 8 0 2 12 0 3 15 3 1 9 3 4 8 2 4 12 2 0
Sample Output
Case 1: 10 Case 2: no solution Case 3: no solution Case 4: 12
题意:从0--n+1,中间有一些路,走的时候起点必须大于终点,每条路都有一定的危险值,每一种方案需要挑选至少K条路,这些路里危险度最大的那条路就是整个方案的危险值,输出最小的危险值,如果没有方案的话输出no solutation!
二分枚举危险度,建图,然后跑一边拆点最大流,每条边容量为1,判断最大流结果是否大于等于k
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; #define MAXN 220*220 #define MAXM 220*220*5 #define INF 0x3f3f3f3f int u[MAXN],v[MAXN],c[MAXN],n,m,k; int head[MAXN],dis[MAXN],cnt,cur[MAXN],vis[MAXN]; struct node { int u,v,cap,flow,next; }edge[MAXM]; void init() { memset(head,-1,sizeof(head)); cnt=0; } void add(int a,int b,int w) { node E={a,b,w,0,head[a]}; edge[cnt]=E; head[a]=cnt++; node E1={b,a,0,0,head[b]}; edge[cnt]=E1; head[b]=cnt++; } bool BFS(int s,int t) { queue<int>q; memset(vis,0,sizeof(vis)); memset(dis,-1,sizeof(dis)); q.push(s); dis[s]=0; vis[s]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { node E=edge[i]; if(E.cap>E.flow&&!vis[E.v]) { dis[E.v]=dis[E.u]+1; vis[E.v]=1; if(E.v==t) return true; q.push(E.v); } } } return false; } int DFS(int x,int a,int e) { if(a==0||e==x) return a; int flow=0,f; for(int &i=cur[x];i!=-1;i=edge[i].next) { node &E=edge[i]; if(dis[E.v]==dis[E.u]+1&&(f=DFS(E.v,min(E.cap-E.flow,a),e))>0) { flow+=f; a-=f; edge[i].flow+=f; edge[i^1].flow-=f; if(a==0) break; } } return flow; } int MAXflow(int s,int t) { int flow=0; while(BFS(s,t)) { memcpy(cur,head,sizeof(head)); flow+=DFS(s,INF,t); } return flow; } bool judge(int x) { init(); for(int i=0;i<m;i++) { if(c[i]<=x) { if(u[i]==0) add(u[i],v[i],1); else add(u[i]+1+n,v[i],1); } } for(int i=1;i<=n+1;i++) add(i,i+1+n,1); return MAXflow(0,n+1)>=k; } int main() { int Case=1; while(scanf("%d",&n)!=EOF) { if(n==0) break; scanf("%d",&m); memset(u,0,sizeof(u)); memset(v,0,sizeof(v)); memset(c,0,sizeof(c)); int r=0; for(int i=0;i<m;i++) { scanf("%d%d%d",&u[i],&v[i],&c[i]); r=max(c[i],r); if(u[i]>v[i]) swap(u[i],v[i]); } scanf("%d",&k); int l=0,ans=0; while(r>=l) { int mid=(l+r)/2; if(judge(mid)) { ans=mid; r=mid-1; } else l=mid+1; } printf("Case %d: ",Case++); if(ans==0) printf("no solution\n"); else printf("%d\n",ans); } return 0; }
以上是关于UVAlive--4529--Dangerous Tunnels(二分+拆点最大流)的主要内容,如果未能解决你的问题,请参考以下文章