poj 2396 Budget–有源匯+有上下界+可行流

來源:互聯網
上載者:User

/*有源匯 有上下界 求可行流有源匯可以轉化為無源匯:添加一條邊t~s (0,0x7fffffff)  就成了無源匯基本流程是:構造附加網路(添加新源 新匯 分離必要弧)求附加網路的最大流若新源 新匯 相鄰的邊都是滿流,則存在可行流題意:有個表格,給出每行的和以及每列的和   還有某些元素的要求求一個合格表格一個比較詳細的講解 http://blog.csdn.net/water_glass/article/details/6823741添加新的源匯後,分離必要弧(必有一端是新源或新匯,必須滿流才有可行流)這時候有兩種(新源ss新匯tt):1.添加  (u,v)流量為上下界之差  (ss,v) 和 (u,tt) 的流量都是  下界流量可以這樣理解:(u,v)流量為上下界之差  是因為要改造成下界流量為0的(ss,v)流量是下界流量  是因為要補充(u,v)中的下界流量,使其直接到v(u,tt)流量是下界流量  從u之前流過來的流量中,無法通過全部(u,v),其下界部分通過這條邊直接到tt上面那篇文站就是這樣講的,但是他寫的時候用的是第二種2.添加  (u,v)流量為上下界之差  (ss,u) 和 (u,tt) 的流量都是  流入u的所有下界流量之和  減去  流出u的所有下界流量之和(有圖)這兩種方法分別是從 邊 點 兩個方面進行的把邊或點的下界分離出來,使所有的邊或點的下界都為0,轉化為普通的最大流問題下界部分直接由ss提供或直接流向tt*/#include<iostream>#include<string>using namespace std;#define N 235int map[N][N],m,n,s,t,x,y,up[N][N],low[N][N],yu[N],num[N],d[N];int min(int a,int b){return a<b?a:b;}int max(int a,int b){return a>b?a:b;}void ini(){memset(low,0,sizeof(low));memset(map,0,sizeof(map));memset(yu,0,sizeof(yu));for(int i=0;i<=m;++i)for(int j=0;j<=n;++j)up[i][j]=0x7fffffff;}int build(){for(int i=1;i<=m;i++)          for(int j=1;j<=n;j++)              if(low[i][j]>up[i][j]) return 0;              else{                  yu[i]-=low[i][j],yu[j+m]+=low[i][j];//這裡的m寫成了nmap[i][j+m]=up[i][j]-low[i][j];            }      return 1;}int sap(int u,int f){if(u==y)//到達終點return f;int v,mind=y,last=f,cost;//mind=點數-1  若從0開始,即為最後那個點for(v=0;v<=y;++v){if(map[u][v]>0){if(d[u]==d[v]+1){cost=sap(v,min(last,map[u][v]));map[u][v]-=cost;map[v][u]+=cost;last-=cost;if(d[x]>=y+1)return f-last;if(last==0)break;}if(d[v]<mind)mind=d[v];}}if(last==f){--num[d[u]];if(num[d[u]]==0)d[x]=y+1;d[u]=mind+1;++num[d[u]];}return f-last;}void limitflow()//{int i,j,c=0;//c最大流的流量x=t+1,y=t+2;//新源 新匯for(i=s;i<=t;++i)if(yu[i]>0) map[x][i]=yu[i];//必要弧else if(yu[i]<0) map[i][y]=-yu[i];//必要弧map[t][s]=0x7fffffff;//把原圖改成無源匯memset(d,0,sizeof(d));memset(num,0,sizeof(num));for(num[x]=y+1;d[x]<y+1;)//y+1點數  c+=sap(x,0x7fffffff);//用sap求最大流for(i=s;i<=t;++i)//判斷是否滿流if(map[x][i]){cout<<"IMPOSSIBLE"<<endl<<endl;return;}for(i=1;i<=m;++i)//輸出可行流{for(j=1;j<n;++j)cout<<(up[i][j]-map[i][j+m])<<" ";//上界-未用可增部分cout<<(up[i][n]-map[i][n+m])<<endl;}cout<<endl;}int main(){int cas,sum1,sum2,i,j,a,b,num,c,f1,f2,t1,t2;string op;cin>>cas;while(cas--){cin>>m>>n;s=0,t=m+n+1,sum1=sum2=0;ini();for(i=1;i<=m;++i) cin>>a,yu[s]-=a,yu[i]+=a,sum1+=a;for(;i<=m+n;++i) cin>>a,yu[i]-=a,yu[t]+=a,sum2+=a;cin>>c;while(c--)//他的處理方法很好{cin>>a>>b>>op>>num;f1=t1=a;f2=t2=b;if(a==0)f1=1,t1=m;if(b==0)f2=1,t2=n;for(i=f1;i<=t1;++i)for(j=f2;j<=t2;++j)if(op[0]=='=')                        low[i][j]=max(num,low[i][j]),up[i][j]=min(num,up[i][j]);                      else if(op[0]=='>')                         low[i][j]=max(num+1,low[i][j]);                      else if(op[0]=='<')                        up[i][j]=min(num-1,up[i][j]);  }if(sum1==sum2&&build()) limitflow();else cout<<"IMPOSSIBLE"<<endl<<endl;}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.