POJ 1459 Power Network【多源汇点最大流】

意:总共N个点,np个源点,nc个汇点,nl条边,求最大流。

建立个超级源,超级汇点就行了,注意下题目给的是0-n-1下标,手动加1无压力。

输入N,NP,NC,NL,然后NL个边,NP个源点,NP个汇点。

然后递归Dinic诡异了,居然TLE,然后EK居然A了(688MS),而Dinic在DFS里加个初始化层次的语句就A了(1157MS)。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define sc(x) scanf("%d",&x);
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
const int maxn=300;
const int maxm=1e6+5;
const int inf = 0x3f3f3f3f;
int cap[maxn][maxn],dis[maxn];
int ss,tt;

int bfs(){
    queue<int>q;
    q.push(ss);
    CLR(dis,-1);
    dis[ss]=0;
    while(!q.empty()){
        int cur=q.front();q.pop();
        FOR(i,ss,tt){
            if(cap[cur][i]&&dis[i]<0){
                dis[i]=dis[cur]+1;
                q.push(i);
            }
        }
    }
    return dis[tt]>0;
}
int dfs(int s,int low){
    int flow;
    if(s==tt)   return low;
    FOR(i,ss,tt){
        if(cap[s][i]
        && (dis[i]==dis[s]+1)
        && (flow=dfs(i,min(low,cap[s][i]))) ){
            cap[s][i]-=flow;
            cap[i][s]+=flow;
            return flow;
        }
    }
    dis[s]=-1;  //不加就TLE
    return 0;
}

int maxFlow(){
    int tans=0;
    while(bfs())
        tans+=dfs(ss,inf);
    return tans;
}

int main(){
//    RE
    int n,np,nc,nl,a,b,c;
    char ch;
    char s1[100];
    while(scanf("%d%d%d%d",&n,&np,&nc,&nl)!=EOF)
    {
        CLR(cap,0);
        ss=0,tt=n+1;
        REP(i,nl)
        {
            scanf("%s",s1);
            sscanf(s1,"(%d,%d)%d",&a,&b,&c);
            if(a==b)    continue;
            cap[a+1][b+1]+=c;
        }
        REP(i,np)
        {
            scanf("%s",s1);
            sscanf(s1,"(%d)%d",&a,&b);
            cap[ss][a+1]=b;
        }
        REP(i,nc)
        {
            scanf("%s",s1);
            sscanf(s1,"(%d)%d",&a,&b);
            cap[a+1][tt]=b;
        }
        printf("%d\n",maxFlow());
    }
    return 0;
}

EK

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define eps 10^(-6)
#define Q_CIN ios::sync_with_stdio(false);
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define debug(x) cout<<#x<<":"<<(x)<<endl;
#define sc(x) scanf("%d",&x);
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
const int maxn=120;
const int maxm=1e6+5;
const int inf = 0x3f3f3f3f;
int cap[maxn][maxn];
int ss,tt;
int flow[maxn][maxn],low[maxn],pre[maxn];

int n;

int EK(int s,int t)
{
    queue<int>q;
    int tans=0;
    CLR(flow,0);
    while(true)
    {
        CLR(low,0);
        q.push(s);
        low[s]=inf;
        while(!q.empty())
        {
            int cur=q.front();q.pop();
            FOR(i,s,t)
            {
                if(!low[i]&&flow[cur][i]<cap[cur][i])
                {
                    low[i]=min(low[cur],cap[cur][i]-flow[cur][i]);
                    q.push(i);
                    pre[i]=cur;
                }
            }
        }
        if(!low[t]) break;
        for(int u=t;u!=s;u=pre[u])
        {
            flow[pre[u]][u]+=low[t];
            flow[u][pre[u]]-=low[t];
        }
        tans+=low[t];
    }
    return tans;
}


int main(){
//    RE
    int np,nc,nl,a,b,c;
    char ch;
    char s1[500];
    while(scanf("%d%d%d%d",&n,&np,&nc,&nl)!=EOF)
    {
        CLR(cap,0);
        ss=0,tt=n+1;
        REP(i,nl)
        {
            scanf("%s",s1);
            sscanf(s1,"(%d,%d)%d",&a,&b,&c);
            if(a==b)    continue;
            cap[a+1][b+1]+=c;
        }
        REP(i,np)
        {
            scanf("%s",s1);
            sscanf(s1,"(%d)%d",&a,&b);
            cap[ss][a+1]=b;
        }
        REP(i,nc)
        {
            scanf("%s",s1);
            sscanf(s1,"(%d)%d",&a,&b);
            cap[a+1][tt]=b;
        }
        printf("%d\n",EK(ss,tt));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值