程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 3801 hdu 3157 Crazy Circuits--有源匯 有上下界 最小流

poj 3801 hdu 3157 Crazy Circuits--有源匯 有上下界 最小流

編輯:C++入門知識

[cpp]
*
hdu 3157
poj 3801
題意:一個電路板,上面有N個接線柱(標號1~N)   還有兩個電源接線柱  +  -
然後是 給出M個部件正負極的接線柱和最小電流
求一個可以讓所有部件正常工作的總電流  沒有則輸出impossible
 
其實就是一個 有源匯 有上下界 最小流 問題
 
處理有源匯有上下界最大流問題是:
1.構造附加網絡
2.對ss、tt求最大流(ss、tt滿流則有解)
3.若有解,對s、t求最大流
 
而有源匯有上下界最小流問題則是:
1.構造附加網絡(不添加[t,s]邊)
2.對ss、tt求最大流
3.添加[t,s]邊
4.對ss、tt求最大流
5.若ss、tt滿流,則[t,s]的流量就是最小流
 
這個代碼大部分都是從別的題上摘過來的,注釋有點亂
*/ 
#include<stdio.h>  
#include<string.h>  
#define inf 0x7fffffff  
struct edge//邊    
{   
    int u,v,f,next,b,c;//邊的 前節點 後節點 可用流 下條邊的編號  原來邊上流的上下界    
}e[1500];   
int head[70],in[70],s,t,ss,tt,yong,sum; 
int n,m; 
void ini() 

    memset(head,-1,sizeof(head)); 
    yong=0; 
    memset(in,0,sizeof(in)); 
    s=0,t=n+1,ss=t+1,tt=ss+1;//各節點編號的安排  
    sum=0; 

void adde(int from,int to,int xia,int shang)//加邊    
{   //加邊    
    e[yong].u=from,e[yong].v=to,e[yong].f=shang-xia,e[yong].b=xia,e[yong].c=shang;   
    e[yong].next=head[from],head[from]=yong++;   
    //同時加它的退邊    
    e[yong].u=to,e[yong].v=from,e[yong].f=0,e[yong].b=xia,e[yong].c=shang;   
    e[yong].next=head[to],head[to]=yong++;   
}  
void build() 

    int i;   
    for(i=0;i<=t;++i)   
    {   
        if(in[i]>0)   
            adde(ss,i,0,in[i]);   
        else   
        {   
            adde(i,tt,0,-in[i]);   
            sum+=(-in[i]);   
        }   
    }  

int d[1000],num[1000]; 
int min(int a,int b){return a<b?a:b;}   
int sap_gap(int u,int f,int s,int t)//遞歸sap    
{   
    if(u==t)   
        return f;   
    int i,v,mind=t,last=f,cost;   
    for(i=head[u];i!=-1;i=e[i].next)   
    {   
        v=e[i].v;   
        int flow=e[i].f;   
        if(flow>0)//參考模版寫的時候把flow寫成了f    
        {   
            if(d[u]==d[v]+1)   
            {   
                cost=sap_gap(v,min(last,flow),s,t);   
                e[i].f-=cost;   
                e[i^1].f+=cost;   
                last-=cost;   
   
                if(d[s]>=t+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[s]=t+1;   
        d[u]=mind+1;   
        ++num[d[u]];   
    }   
    return f-last;   
}   
int max_f(int s,int t) 

    int f=0;   
    memset(d,0,sizeof(d));   
    memset(num,0,sizeof(num));   
    for(num[s]=t+1;d[s]<t+1;)   
        f+=sap_gap(s,inf,s,t);   
    return f;  

int main() 

    int i,dat,u,v,f1,f2,p; 
    char from[10],to[10]; 
    while(scanf("%d%d",&n,&m),n+m) 
    { 
        ini(); 
        for(i=1;i<=m;++i) 
        { 
            scanf("%s%s%d",from,to,&dat); 
            if(from[0]=='+') u=s; 
            else sscanf(from,"%d",&u); 
            if(to[0]=='-') v=t; 
            else sscanf(to,"%d",&v); 
            adde(u,v,dat,inf); 
            in[u]-=dat,in[v]+=dat; 
        } 
        build(); 
 
        f1=max_f(ss,tt); 
        p=yong; 
        adde(t,s,0,inf); 
        f2=max_f(ss,tt); 
        if(f1+f2!=sum) printf("impossible\n"); 
        else printf("%d\n",e[p^1].f); 
    } 
    return 0; 

/*
hdu 3157
poj 3801
題意:一個電路板,上面有N個接線柱(標號1~N)   還有兩個電源接線柱  +  -
然後是 給出M個部件正負極的接線柱和最小電流
求一個可以讓所有部件正常工作的總電流  沒有則輸出impossible

其實就是一個 有源匯 有上下界 最小流 問題

處理有源匯有上下界最大流問題是:
1.構造附加網絡
2.對ss、tt求最大流(ss、tt滿流則有解)
3.若有解,對s、t求最大流

而有源匯有上下界最小流問題則是:
1.構造附加網絡(不添加[t,s]邊)
2.對ss、tt求最大流
3.添加[t,s]邊
4.對ss、tt求最大流
5.若ss、tt滿流,則[t,s]的流量就是最小流

這個代碼大部分都是從別的題上摘過來的,注釋有點亂
*/
#include<stdio.h>
#include<string.h>
#define inf 0x7fffffff
struct edge//邊 

    int u,v,f,next,b,c;//邊的 前節點 後節點 可用流 下條邊的編號  原來邊上流的上下界 
}e[1500]; 
int head[70],in[70],s,t,ss,tt,yong,sum;
int n,m;
void ini()
{
 memset(head,-1,sizeof(head));
 yong=0;
 memset(in,0,sizeof(in));
 s=0,t=n+1,ss=t+1,tt=ss+1;//各節點編號的安排
 sum=0;
}
void adde(int from,int to,int xia,int shang)//加邊 
{ //加邊 
    e[yong].u=from,e[yong].v=to,e[yong].f=shang-xia,e[yong].b=xia,e[yong].c=shang; 
    e[yong].next=head[from],head[from]=yong++; 
 //同時加它的退邊 
    e[yong].u=to,e[yong].v=from,e[yong].f=0,e[yong].b=xia,e[yong].c=shang; 
    e[yong].next=head[to],head[to]=yong++; 
}
void build()
{
 int i; 
    for(i=0;i<=t;++i) 
    { 
        if(in[i]>0) 
            adde(ss,i,0,in[i]); 
        else 
        { 
            adde(i,tt,0,-in[i]); 
            sum+=(-in[i]); 
        } 
    }
}
int d[1000],num[1000];
int min(int a,int b){return a<b?a:b;} 
int sap_gap(int u,int f,int s,int t)//遞歸sap 

    if(u==t) 
        return f; 
    int i,v,mind=t,last=f,cost; 
    for(i=head[u];i!=-1;i=e[i].next) 
    { 
        v=e[i].v; 
        int flow=e[i].f; 
        if(flow>0)//參考模版寫的時候把flow寫成了f 
        { 
            if(d[u]==d[v]+1) 
            { 
                cost=sap_gap(v,min(last,flow),s,t); 
                e[i].f-=cost; 
                e[i^1].f+=cost; 
                last-=cost; 
 
                if(d[s]>=t+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[s]=t+1; 
        d[u]=mind+1; 
        ++num[d[u]]; 
    } 
    return f-last; 

int max_f(int s,int t)
{
    int f=0; 
    memset(d,0,sizeof(d)); 
    memset(num,0,sizeof(num)); 
    for(num[s]=t+1;d[s]<t+1;) 
        f+=sap_gap(s,inf,s,t); 
    return f;
}
int main()
{
 int i,dat,u,v,f1,f2,p;
 char from[10],to[10];
 while(scanf("%d%d",&n,&m),n+m)
 {
  ini();
  for(i=1;i<=m;++i)
  {
   scanf("%s%s%d",from,to,&dat);
   if(from[0]=='+') u=s;
   else sscanf(from,"%d",&u);
   if(to[0]=='-') v=t;
   else sscanf(to,"%d",&v);
   adde(u,v,dat,inf);
   in[u]-=dat,in[v]+=dat;
  }
  build();

  f1=max_f(ss,tt);
  p=yong;
  adde(t,s,0,inf);
  f2=max_f(ss,tt);
  if(f1+f2!=sum) printf("impossible\n");
  else printf("%d\n",e[p^1].f);
 }
 return 0;
}作者:qq172108805
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved