• BZOJ1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛


    n<=200个点m<=1500条无向带权边的图,每个点有人和容量,人可以移动,代价为所有人走过的边的权和,求使所有点人不超过容量的最小代价。

    方法一:费用流。

    错误!答案与边权不成比例。

    方法二:二分一个答案,然后根据floyd求出的最短路看每个点在二分的答案下能去到哪些点,跑最大流检查是否合法。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<algorithm>
      5 //#include<iostream>
      6 using namespace std;
      7 
      8 int n,m;
      9 #define maxn 411
     10 #define maxm 100011
     11 #define LL long long
     12 int a[maxn],b[maxn],sum=0;
     13 LL mp[maxn][maxn];
     14 const LL inf=1e15;
     15 struct Edge{int from,to,next,cap,flow;};
     16 struct Network
     17 {
     18     Edge edge[maxm];int n,s,t,le;
     19     int first[maxn],dis[maxn],cur[maxn];
     20     void clear(int n)
     21     {
     22         memset(first,0,sizeof(first));
     23         le=2;this->n=n;
     24     }
     25     void add_edge(int x,int y,int v)
     26     {
     27         Edge &e=edge[le];
     28         e.to=y;e.from=x;
     29         e.cap=v;e.flow=0;
     30         e.next=first[x];
     31         first[x]=le++;
     32     }
     33     void insert(int x,int y,int v)
     34     {
     35         add_edge(x,y,v);
     36         add_edge(y,x,0);
     37     }
     38     int que[maxn],head,tail;
     39     bool bfs()
     40     {
     41         memset(dis,0,sizeof(dis));
     42         dis[s]=1;
     43         que[head=(tail=1)-1]=s;
     44         while (head!=tail)
     45         {
     46             const int x=que[head++];
     47             for (int i=first[x];i;i=edge[i].next)
     48             {
     49                 Edge &e=edge[i];
     50                 if (e.cap>e.flow && !dis[e.to])
     51                 {
     52                     dis[e.to]=dis[x]+1;
     53                     que[tail++]=e.to;
     54                 }
     55             }
     56         }
     57         return dis[t];
     58     }
     59     int dfs(int x,int a)
     60     {
     61         if (x==t || !a) return a;
     62         int flow=0,f;
     63         for (int &i=cur[x];i;i=edge[i].next)
     64         {
     65             Edge &e=edge[i];
     66             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0)
     67             {
     68                 flow+=f;
     69                 a-=f;
     70                 e.flow+=f;
     71                 edge[i^1].flow-=f;
     72                 if (!a) break;
     73             }
     74         }
     75         return flow;
     76     }
     77     int Dinic(int s,int t)
     78     {
     79         this->s=s;this->t=t;
     80         int ans=0;
     81         while (bfs())
     82         {
     83             for (int i=1;i<=n;i++) cur[i]=first[i];
     84             ans+=dfs(s,0x3f3f3f3f);
     85         }
     86         return ans;
     87     }
     88 }g;
     89 bool check(LL x)
     90 {
     91     g.clear(n*2+2);
     92     int s=g.n-1,t=g.n;
     93     for (int i=1;i<=n;i++)
     94     {
     95         g.insert(s,i,a[i]);
     96         g.insert(i+n,t,b[i]);
     97     }
     98     for (int i=1;i<=n;i++)
     99         for (int j=1;j<=n;j++)
    100             if (mp[i][j]<=x) g.insert(i,j+n,0x3f3f3f3f);
    101     return g.Dinic(s,t)==sum;
    102 }
    103 int x,y,v;
    104 int main()
    105 {
    106     scanf("%d%d",&n,&m);
    107     for (int i=1;i<=n;i++)
    108         scanf("%d%d",&a[i],&b[i]),sum+=a[i];
    109     for (int i=1;i<=n;i++)
    110         for (int j=1;j<=n;j++)
    111             mp[i][j]=inf;
    112     for (int i=1;i<=n;i++) mp[i][i]=0;
    113     for (int i=1;i<=m;i++)
    114     {
    115         scanf("%d%d%d",&x,&y,&v);
    116         mp[x][y]=min(mp[x][y],(LL)v);
    117         mp[y][x]=min(mp[y][x],(LL)v);
    118     }
    119     for (int k=1;k<=n;k++)
    120         for (int i=1;i<=n;i++)
    121             for (int j=1;j<=n;j++)
    122                 if (mp[i][j]>mp[i][k]+mp[k][j])
    123                     mp[i][j]=mp[i][k]+mp[k][j];
    124     LL L=0,R=1e15;
    125     while (L<R)
    126     {
    127         const LL mid=(L+R)>>1;
    128         if (check(mid)) R=mid;
    129         else L=mid+1;
    130     }
    131     printf(R==1e15?"-1
    ":"%lld
    ",L);
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    sql中触发器的使用
    sql中优化查询
    sql中case when语句的使用
    CSRF学习小结
    javascript正则表达式笔记
    elementUI单选框获取值
    elementUI内置过渡(折叠)
    elementUI内置缩放过渡(缩放)
    elementUi内置过渡动画(淡入)
    创建koa2项目
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7522265.html
Copyright © 2020-2023  润新知