zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    146         }else
    147             puts("no solution");
    148     }
    149     return 0;
    150 }
    View Code
  • 相关阅读:
    Quartz学习笔记
    apache shiro学习笔记
    zTree学习笔记
    WebService学习笔记
    【webservice】Two classes have the same XML type name(转)
    使用OCUpload和POI一键上传Excel并解析导入数据库
    EasyUI学习笔记(四)—— datagrid的使用
    thinkphp的路径问题
    thinkphp验证码不现实多半是bom惹的祸
    TPM(ThinkPHPMobile)使用简明教程
  • 原文地址:https://www.cnblogs.com/wally/p/3354735.html
Copyright © 2011-2022 走看看