• [bzoj1738]发抖的牛


    二分答案,每一头牛向所有在规定时间内能走到的牛棚连inf的边,每一个源点向牛连牛数量的边,每一个牛棚向汇点连牛棚容量的边,能满流则意味着这个答案可行,否则不可行。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 505
     4 #define ll long long
     5 #define inf 0x3f3f3f3f
     6 struct ji{
     7     int nex,to,len;
     8 }e[N*N],edge[N*N];
     9 queue<int>q;
    10 int E,EE,n,m,x,y,z,s,a[N],d[N],head[N],work[N];
    11 ll f[N][N];
    12 void add(int x,int y,int z){
    13     edge[E].nex=head[x];
    14     edge[E].to=y;
    15     edge[E].len=z;
    16     head[x]=E++;
    17     if (E&1)add(y,x,0); 
    18 }
    19 bool bfs(){
    20     q.push(0);
    21     memset(d,-1,sizeof(d));
    22     d[0]=0;
    23     while (!q.empty()){
    24         int k=q.front();
    25         q.pop();
    26         for(int i=head[k];i!=-1;i=edge[i].nex)
    27             if ((edge[i].len)&&(d[edge[i].to]<0)){
    28                 d[edge[i].to]=d[k]+1;
    29                 q.push(edge[i].to);
    30             }
    31     }
    32     return d[n]>=0;
    33 }
    34 int dfs(int k,int s){
    35     if (k==n)return s;
    36     int p;
    37     for(int &i=work[k];i!=-1;i=edge[i].nex)
    38         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
    39             p=dfs(edge[i].to,min(s,edge[i].len));
    40             if (p){
    41                 edge[i].len-=p;
    42                 edge[i^1].len+=p;
    43                 return p;
    44             }
    45         }
    46     return 0;
    47 }
    48 int dinic(){
    49     int k,ans=0;
    50     while (bfs()){
    51         memcpy(work,head,sizeof(work));
    52         while (k=dfs(0,inf))ans+=k;
    53     }
    54     return ans;
    55 }
    56 bool pd(ll k){
    57     for(int i=1;i<=n/2;i++)
    58         for(int j=1;j<=n/2;j++)
    59             if (f[i][j]<=k)add(i,j+n/2,inf);
    60     int t=dinic();
    61     memcpy(head,a,sizeof(a));
    62     memcpy(edge,e,sizeof(e));
    63     E=EE;
    64     return t==s;
    65 }
    66 int main(){
    67     scanf("%d%d",&n,&m);
    68     memset(head,-1,sizeof(head));
    69     for(int i=1;i<=n;i++){
    70         scanf("%d%d",&x,&y);
    71         add(0,i,y);
    72         add(n+i,2*n+1,x);
    73         s+=x;
    74     }
    75     memset(f,inf,sizeof(f));
    76     for(int i=1;i<=n;i++)f[i][i]=0;
    77     for(int i=1;i<=m;i++){
    78         scanf("%d%d%d",&x,&y,&z);
    79         f[x][y]=f[y][x]=min(f[x][y],1LL*z);
    80     }
    81     for(int i=1;i<=n;i++)
    82         for(int j=1;j<=n;j++)
    83             for(int k=1;k<=n;k++)
    84                 f[j][k]=min(f[j][k],f[j][i]+f[i][k]);
    85     n=n*2+1;
    86     ll l=0,r=2e11;
    87     memcpy(a,head,sizeof(a));
    88     memcpy(e,edge,sizeof(e));
    89     EE=E;
    90     while (l<r){
    91         ll mid=(l+r>>1);
    92         if (pd(mid))r=mid;
    93         else l=mid+1;
    94     }
    95     if (l==2e11)l=-1;
    96     printf("%lld",l);
    97 }
    View Code
  • 相关阅读:
    linux常用小技巧(持续更新中)
    【CodeBase】PHP将数组键名转成变量名
    【Mysql】给mysql配置远程登录
    【Codebase】JQuery获取表单部分数据提交方法
    【shopex】添加网页挂件widgets
    【shopex】真正可用的app开发机制
    【转】Mysql查询语句优化策略
    【Ecshop】修改处理用户购物车的行为
    【Ecshop】商品数据采集扩展
    supervisor 使用
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249618.html
Copyright © 2020-2023  润新知