loj 1167(二分+最大流)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26881

思路:我们可以二分最大危险度,然后建图,由于每个休息点只能用一次,就要拆点,将每个休息点拆点,边容量为1,代表只能使用一次,然后跑最大流验证。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cmath>
  7 using namespace std;
  8 #define MAXN 222
  9 #define MAXM 222222
 10 #define inf 1<<30
 11 #define FILL(a,b) memset(a,b,sizeof(a))
 12 
 13 struct Edge{
 14     int v,cap,next;
 15 }edge[MAXM];
 16 
 17 int n,m,vs,vt,k,NV,NE;
 18 int head[MAXN];
 19 
 20 void Insert(int u,int v,int cap)
 21 {
 22     edge[NE].v=v;
 23     edge[NE].cap=cap;
 24     edge[NE].next=head[u];
 25     head[u]=NE++;
 26 
 27     edge[NE].v=u;
 28     edge[NE].cap=0;
 29     edge[NE].next=head[v];
 30     head[v]=NE++;
 31 }
 32 
 33 int level[MAXN],gap[MAXN];
 34 void bfs(int vt)
 35 {
 36     FILL(level,-1);
 37     FILL(gap,0);
 38     queue<int>que;
 39     level[vt]=0;
 40     gap[0]++;
 41     que.push(vt);
 42     while(!que.empty()){
 43         int u=que.front();
 44         que.pop();
 45         for(int i=head[u];i!=-1;i=edge[i].next){
 46             int v=edge[i].v;
 47             if(level[v]!=-1)continue;
 48             level[v]=level[u]+1;
 49             gap[level[v]]++;
 50             que.push(v);
 51         }
 52     }
 53 }
 54 
 55 int pre[MAXN],cur[MAXN];
 56 int SAP(int vs,int vt)
 57 {
 58     bfs(vt);
 59     memcpy(cur,head,sizeof(head));
 60     int u=pre[vs]=vs,aug=inf,maxflow=0;
 61     gap[0]=NV;
 62     while(level[vs]<NV){
 63         bool flag=false;
 64         for(int &i=cur[u];i!=-1;i=edge[i].next){
 65             int v=edge[i].v;
 66             if(edge[i].cap>0&&level[u]==level[v]+1){
 67                 flag=true;
 68                 aug=min(aug,edge[i].cap);
 69                 pre[v]=u;
 70                 u=v;
 71                 if(v==vt){
 72                     maxflow+=aug;
 73                     for(u=pre[u];v!=vs;v=u,u=pre[u]){
 74                         edge[cur[u]].cap-=aug;
 75                         edge[cur[u]^1].cap+=aug;
 76                     }
 77                     aug=inf;
 78                 }
 79                 break;
 80             }
 81         }
 82         if(flag)continue;
 83         int minlevel=NV;
 84         for(int i=head[u];i!=-1;i=edge[i].next){
 85             int v=edge[i].v;
 86             if(edge[i].cap>0&&level[v]<minlevel){
 87                 minlevel=level[v];
 88                 cur[u]=i;
 89             }
 90         }
 91         if(--gap[level[u]]==0)break;
 92         level[u]=minlevel+1;
 93         gap[level[u]]++;
 94         u=pre[u];
 95     }
 96     return maxflow;
 97 }
 98 
 99 struct Path{
100     int u,v,d;
101 }path[MAXM];
102 
103 void Build(int limit)
104 {
105     NE=0;
106     memset(head,-1,sizeof(head));
107     vs=0,vt=2*n+3,NV=2*n+4;
108     for(int i=0;i<m;i++){
109         if(path[i].d<=limit)Insert(path[i].u+n+2,path[i].v,1);
110     }
111     for(int i=1;i<=n;i++)Insert(i,i+n+2,1);
112     Insert(vs,vs+n+2,11);
113     Insert(n+1,vt,11);
114 }
115 
116 
117 int main()
118 {
119     int _case,u,v,d,low,high,mid,ans,t=1;
120     scanf("%d",&_case);
121     while(_case--){
122         scanf("%d%d",&n,&m);
123         low=inf,high=0;
124         for(int i=0;i<m;i++){
125             scanf("%d%d%d",&path[i].u,&path[i].v,&path[i].d);
126             if(path[i].u>path[i].v)swap(path[i].u,path[i].v);
127             //cout<<path[i].u<<"&&&&"<<path[i].v<<endl;
128             low=min(low,path[i].d);
129             high=max(high,path[i].d);
130         }
131        // cout<<low<<"**"<<high<<endl;
132         scanf("%d",&k);
133         ans=inf;
134         while(low<=high){
135             mid=(low+high)>>1;
136             Build(mid);
137             if(SAP(vs,vt)>=k){
138                 ans=mid;
139                 high=mid-1;
140             }else
141                 low=mid+1;
142         }
143         printf("Case %d: ",t++);
144         if(ans!=inf){
145             printf("%d\n",ans);
146         }else
147             puts("no solution");
148     }
149     return 0;
150 }
View Code

 

posted @ 2013-10-06 22:16  ihge2k  阅读(210)  评论(0编辑  收藏  举报