• poj 3228(二分+最大流)


    题目链接:http://poj.org/problem?id=3228

    思路:增设一个超级源点和一个超级汇点,源点与每一个gold相连,容量为gold数量,汇点与仓库相连,容量为仓库的容量,然后就是二分最小的最大相邻距离,跑最大流验证即可。最大流用的是别人的Dinic模版。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 #define MAXN 222
      8 #define inf 1<<30
      9 
     10 int vs,vt;
     11 int dep[MAXN];
     12 int map[MAXN][MAXN];
     13 
     14 int gold[MAXN],store[MAXN];
     15 int dist[MAXN][MAXN];
     16 void Build_Map(int limit,int n)
     17 {
     18     memset(map,0,sizeof(map));
     19     for(int i=1;i<=n;i++)
     20         for(int j=1;j<=n;j++)
     21             if(dist[i][j]<=limit)map[i][j]=inf;
     22     for(int i=1;i<=n;i++){
     23         map[vs][i]=gold[i];
     24         map[i][vt]=store[i];
     25     }
     26 }
     27 
     28 int BFS(){
     29     queue<int> q;
     30     while(!q.empty())
     31         q.pop();
     32     memset(dep,-1,sizeof(dep));
     33     dep[vs]=0;
     34     q.push(vs);
     35     while(!q.empty()){
     36         int u=q.front();
     37         q.pop();
     38         for(int v=vs;v<=vt;v++)
     39             if(map[u][v]>0 && dep[v]==-1){
     40                 dep[v]=dep[u]+1;
     41                 q.push(v);
     42             }
     43     }
     44     return dep[vt]!=-1;
     45 }
     46 
     47 int DFS(int u,int minx){
     48     if(u==vt)
     49         return minx;
     50     int tmp;
     51     for(int v=vs;v<=vt;v++)
     52         if(map[u][v]>0 && dep[v]==dep[u]+1 && (tmp=DFS(v,min(minx,map[u][v])))){
     53             map[u][v]-=tmp;
     54             map[v][u]+=tmp;
     55             return tmp;
     56         }
     57     dep[u]=-1;
     58     return 0;
     59 }
     60 
     61 int Dinic(){
     62     int ans=0,tmp;
     63     while(BFS()){
     64         while(1){
     65             tmp=DFS(vs,inf);
     66             if(tmp==0)
     67                 break;
     68             ans+=tmp;
     69         }
     70     }
     71     return ans;
     72 }
     73 
     74 int main()
     75 {
     76     int total,n,m,a,b,c;
     77     while(~scanf("%d",&n)){
     78         if(n==0)break;
     79         total=0,vs=0,vt=n+1;
     80         for(int i=1;i<=n;i++)
     81             for(int j=1;j<=n;j++)
     82                 dist[i][j]=inf;
     83         for(int i=1;i<=n;i++){
     84             scanf("%d",&gold[i]);
     85             total+=gold[i];
     86         }
     87         for(int i=1;i<=n;i++)scanf("%d",&store[i]);
     88         scanf("%d",&m);
     89         while(m--){
     90             scanf("%d%d%d",&a,&b,&c);
     91             dist[a][b]=dist[b][a]=c;
     92         }
     93         
     94         int low=0,high=100010,mid,ans=-1;
     95         while(low<=high){
     96             mid=(low+high)>>1;
     97             Build_Map(mid,n);
     98             if(Dinic()==total){
     99                 ans=mid;
    100                 high=mid-1;
    101             }else 
    102                 low=mid+1;
    103         }
    104         if(ans==-1){
    105             printf("No Solution
    ");
    106         }else 
    107             printf("%d
    ",ans);
    108     }
    109     return 0;
    110 }
    111 
    112 
    113         
    View Code
  • 相关阅读:
    vue 侦听器
    vue 计算属性
    typeof 运算符
    constructor 属性
    立即执行函数与闭包
    计算属性缓存 vs 方法
    JavaScrip备课
    winform 实现对usb热拔插的监听
    c# async await的使用方式及为啥要用它
    .net5与之前的版本GetBytes长度变化
  • 原文地址:https://www.cnblogs.com/wally/p/3192065.html
Copyright © 2020-2023  润新知