• poj2396 Budget(有源汇上下界可行流)


    【题目链接】

        http://poj.org/problem?id=2396

    【题意】

        知道一个矩阵的行列和,且知道一些格子的限制条件,问一个可行的方案。

    【思路】

        设行为X点,列为Y点,构图:连边(s,Xi,sumXi,sumXi)(Yi,t,sumYi,sumYi)(Xi,Yj,down[i][j],up[i][j])。

        则问题就是求一个有源汇点st的上下界可行流。

        类似于 无源无汇上下界可行流 ,添加附加源汇点ST,边权转化为up-down,由ST向每个点连边保持流量平衡。然后添加(t,s,inf),使得t的流出量与s的流入量保持相等,即等价于s为源点而t为汇点。

        最后由S->T跑最大流。

    【代码】

      1 #include<set>
      2 #include<cmath>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
     10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 const int N = 4e2+10;
     15 const int M = N*N+10;
     16 const int inf = 1e9;
     17 
     18 ll read() {
     19     char c=getchar();
     20     ll f=1,x=0;
     21     while(!isdigit(c)) {
     22         if(c=='-') f=-1; c=getchar();
     23     }
     24     while(isdigit(c))
     25         x=x*10+c-'0',c=getchar();
     26     return x*f;
     27 }
     28 
     29 struct Edge {
     30     int u,v,cap,flow;
     31     Edge(int u=0,int v=0,int cap=0,int flow=0)
     32         :u(u),v(v),cap(cap),flow(flow){}
     33 };
     34 struct Dinic {
     35     int n,m,s,t;
     36     int d[N],cur[N],vis[N];
     37     vector<int> g[N];
     38     vector<Edge> es;
     39     queue<int> q;
     40     void init(int n) {
     41         this->n=n;
     42         es.clear();
     43         FOR(i,0,n) g[i].clear();
     44     }
     45     void clear() {
     46         FOR(i,0,(int)es.size()-1) es[i].flow=0;
     47     }
     48     void AddEdge(int u,int v,int w) {
     49         es.push_back(Edge(u,v,w,0));
     50         es.push_back(Edge(v,u,0,0));
     51         m=es.size();
     52         g[u].push_back(m-2);
     53         g[v].push_back(m-1);
     54     }
     55     int bfs() {
     56         memset(vis,0,sizeof(vis));
     57         q.push(s); d[s]=0; vis[s]=1;
     58         while(!q.empty()) {
     59             int u=q.front(); q.pop();
     60             FOR(i,0,(int)g[u].size()-1) {
     61                 Edge& e=es[g[u][i]];
     62                 int v=e.v;
     63                 if(!vis[v]&&e.cap>e.flow) {
     64                     vis[v]=1;
     65                     d[v]=d[u]+1;
     66                     q.push(v);
     67                 }
     68             }
     69         }
     70         return vis[t];
     71     }
     72     int dfs(int u,int a) {
     73         if(u==t||!a) return a;
     74         int flow=0,f;
     75         for(int& i=cur[u];i<g[u].size();i++) {
     76             Edge& e=es[g[u][i]];
     77             int v=e.v;
     78             if(d[v]==d[u]+1&&(f=dfs(v,min(a,e.cap-e.flow)))>0) {
     79                 e.flow+=f; 
     80                 es[g[u][i]^1].flow-=f;
     81                 flow+=f; a-=f;
     82                 if(!a) break;
     83             }
     84         }
     85         return flow;
     86     }
     87     int MaxFlow(int s,int t) {
     88         this->s=s,this->t=t;
     89         int flow=0;
     90         while(bfs()) {
     91             memset(cur,0,sizeof(cur));
     92             flow+=dfs(s,inf);
     93         }
     94         return flow;
     95     }
     96 } dc;
     97 
     98 int n,m,flag;
     99 int in[N],up[N][N],down[N][N];
    100 
    101 void can(int x,int y,int v) {
    102     if(v<down[x][y]||v>up[x][y]) flag=1;
    103 }
    104 
    105 int main()
    106 {
    107     int kase=read();
    108     while(kase--) 
    109     {
    110         memset(in,0,sizeof(in));
    111         n=read(),m=read();
    112         flag=0;
    113         int x,s=n+m+1,t=s+1,S=t+1,T=S+1;
    114         dc.init(n+m+5);
    115         FOR(i,1,n) {
    116             x=read(); in[s]-=x,in[i]+=x;
    117             dc.AddEdge(s,i,0);
    118         }
    119         FOR(i,1,m) {
    120             x=read(); in[n+i]-=x,in[t]+=x;
    121             dc.AddEdge(i+n,t,0);
    122         }
    123         int K=read();
    124         FOR(i,1,n+m+5) FOR(j,1,n+m+5)
    125             up[i][j]=1000,down[i][j]=-1000;
    126         while(K--) {
    127             char s[2];
    128             int x=read(),y=read(),z;
    129             scanf("%s",s); z=read();
    130             if(x==0 && y) {
    131                 FOR(i,1,n) {
    132                     if(s[0]=='=') can(i,y+n,z),up[i][y+n]=down[i][y+n]=z;
    133                     if(s[0]=='<') up[i][y+n]=min(up[i][y+n],z-1);
    134                     if(s[0]=='>') down[i][y+n]=max(down[i][y+n],z+1);
    135                 }
    136             } else
    137             if(x && y==0) {
    138                 FOR(i,1,m) {
    139                     if(s[0]=='=') can(x,i+n,z),up[x][i+n]=down[x][i+n]=z;
    140                     if(s[0]=='<') up[x][i+n]=min(up[x][i+n],z-1);
    141                     if(s[0]=='>') down[x][i+n]=max(down[x][i+n],z+1);
    142                 }
    143             } else
    144             if(x==0 && y==0) {
    145                 FOR(i,1,n) FOR(j,1,m) {
    146                     if(s[0]=='=') can(i,j+n,z),up[i][j+n]=down[i][j+n]=z;
    147                     if(s[0]=='<') up[i][j+n]=min(up[i][j+n],z-1);
    148                     if(s[0]=='>') down[i][j+n]=max(down[i][j+n],z+1);
    149                 }
    150             } else {
    151                 if(s[0]=='=') can(x,y+n,z),up[x][y+n]=down[x][y+n]=z;
    152                 if(s[0]=='<') up[x][y+n]=min(up[x][y+n],z-1);
    153                 if(s[0]=='>') down[x][y+n]=max(down[x][y+n],z+1);
    154             }
    155         }
    156         int cur=dc.es.size();
    157         FOR(i,1,n) FOR(j,1,m) {
    158             if(up[i][j+n]<down[i][j+n]) flag=1;
    159             dc.AddEdge(i,j+n,up[i][j+n]-down[i][j+n]);
    160             in[i]-=down[i][j+n];
    161             in[j+n]+=down[i][j+n];
    162         }
    163         dc.AddEdge(t,s,inf);
    164         if(flag) { puts("IMPOSSIBLE"); continue; }
    165         int sum=0;
    166         FOR(i,1,t) {
    167             if(in[i]>0) dc.AddEdge(S,i,in[i]),sum+=in[i];
    168             if(in[i]<0) dc.AddEdge(i,T,-in[i]);
    169         }
    170         if(sum!=dc.MaxFlow(S,T)) { puts("IMPOSSIBLE"); continue; }
    171         else {
    172             FOR(i,1,n) FOR(j,1,m) {
    173                 printf("%d",dc.es[cur].flow+down[i][j+n]);
    174                 if(j!=m) putchar(' '); else puts("");
    175                 cur+=2;
    176             }
    177         }
    178     }
    179     return 0;
    180 }
  • 相关阅读:
    Document
    Document
    Document
    2.原型和原型链的关系以及查找顺序
    1.面向对象 及 相关知识点
    时间对象 <-> 定时器 <-> 电子时钟 <-> 倒计时效果
    定时器
    let var const 的区别
    ES6 中块的概念
    js中的闭包
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5314892.html
Copyright © 2020-2023  润新知