2013-2014 ACM-ICPC, NEERC, Southern Subregional Contest Problem I. Plugs and Sockets 费用流

Problem I. Plugs and Sockets

题目连接:

http://www.codeforces.com/gym/100253

Description

The Berland Regional Contest will be held in the main hall of the Berland State University. The university
has a real international status. That’s why the power sockets in the main hall are not of the same type.
Some power sockets use the Berland standard of 330 volts at 40 Hz, but other sockets use the Beuropean
standard of 125 volts at 60 Hz.
The technical committee has n computers of three types. The computers of the rst type have power
plugs to plug them in Berland sockets (of 330 volts), the computers of the second type have plugs to plug
them in Beuropean sockets (of 125 volts). The most universal type is the third type, they can be plugged
into any socket, it doesn’t matter if the socket uses the Berland standard or the Beuropean standard.
Also the computers dier by power consumption, the i-th computer consumes wi watts per hour.
The technical committee has to solve a dicult problem. Which computers should they use and how to
plug them in the order to maximize the number of plugged computers? A single socket can be used for at
most one plug. If there are many ways to choose the maximum number of computers to plug, the technical
committee wants to nd the way to minimize the total power consumption of the chosen computers.

Input

The rst line of the input contains n, a and b (1 ≤ n ≤ 5000; 0 ≤ a, b ≤ 5000)  the number of computers
the technical committee has, the number of Berland standard sockets and the number of Beuropean
standard sockets in the hall. The following n lines contain computers’ descriptions, one description per
line. Each description is a pair of two positive integer numbers ti and wi (1 ≤ ti ≤ 3; 1 ≤ wi ≤ 5000) 
the type of the i-th computer and its power consumption.

Output

On the rst line print the maximum number of computers that can be plugged and the required minimum
total power consumption. Then print a single line for each plugged computer with two integer numbers
j and fj (1 ≤ j ≤ n; 1 ≤ fj ≤ a + b) meaning that the j-th computer should be connected to the fj -th
socket. The computers are numbered from 1 to n in the order of the input and sockets are numbered from
1 to a + b in such way that the rst a sockets use the Berland standard and the sockets a + 1, a + 2, . . . ,
a + b use the Beuropean standard. Print the lines in any order. If there are multiple answers, print any of
them.

Sample Input

5 1 2
1 2
1 1
3 10
2 20
2 15

Sample Output

3 26
2 1
5 2
3 3

Hint

题意

裸的费用流

题解:

代码

#include <bits/stdc++.h>
#define rep(a,b,c) for(int (a)=(b);(a)<=(c);++(a))
#define drep(a,b,c) for(int (a)=(b);(a)>=(c);--(a))
#define pb push_back
#define mp make_pair
#define sf scanf
#define pf printf
#define two(x) (1<<(x))
#define clr(x,y) memset((x),(y),sizeof((x)))
#define dbg(x) cout << #x << "=" << x << endl;
const int mod = 1e9 + 7;
int mul(int x,int y){return 1LL*x*y%mod;}
int qpow(int x , int y){int res=1;while(y){if(y&1) res=mul(res,x) ; y>>=1 ; x=mul(x,x);} return res;}
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
using namespace std;

struct ZKW_MinCostMaxFlow{  

    const static int maxn = 1e5 + 50;
    const static int maxE = 1e5 + 50;
    const static int INF = 0x3f3f3f3f;

    struct Edge{  
        int to,next,cap,flow,cost;  
        Edge(int _to=0,int _next=0,int _cap=0,int _flow=0,int _cost=0):  
            to(_to),next(_next),cap(_cap),flow(_flow),cost(_cost){}  
    }edge[maxE * 2];  

    int head[maxn],tot;  
    int cur[maxn];  
    int dis[maxn];  
    bool vis[maxn];  
    int ss,tt,N;  
    int min_cost,max_flow;  
    void init(int N){  
        tot=0;
        for( int i = 0 ; i < N ; ++ i ) head[i] = -1;
    }  
    int addedge(int u,int v,int cap,int cost){  
        edge[tot]=Edge(v,head[u],cap,0,cost);  
        int rs = tot;
        head[u]=tot++;  
        edge[tot]=Edge(u,head[v],0,0,-cost);  
        head[v]=tot++;  
        return rs;
    }  
    int aug(int u,int flow){  
        if(u==tt) return flow;  
        vis[u]=true;  
        for(int i=cur[u];i!=-1;i=edge[i].next){  
            int v=edge[i].to;  
            if( edge[i].cap>edge[i].flow && !vis[v] && dis[u]==dis[v]+edge[i].cost ){  
                int tmp=aug(v,min(flow,edge[i].cap-edge[i].flow));  
                edge[i].flow+=tmp;  
                edge[i^1].flow-=tmp;  
                cur[u]=i;  
                if(tmp) return tmp;  
            }  
        }  
        return 0;  
    }  
    bool modify_label(){  
        int d=INF;  
        for(int u=0;u<N;u++){  
            if(vis[u])  
            for(int i=head[u];i!=-1;i=edge[i].next){  
                int v=edge[i].to;  
                if(edge[i].cap>edge[i].flow && !vis[v])  
                    d=min(d,dis[v]+edge[i].cost-dis[u]);  
            }  
        }  
        if(d==INF) return false;  
            for(int i=0;i<N;i++)  
            if(vis[i]){  
                vis[i]=false;  
                dis[i]+=d;  
            }  
        return true;  
    }  
    pair < int , int > mincostmaxflow(int start,int ed,int n ){  
        ss=start,tt=ed,N=n;  
        min_cost=max_flow=0;  
        for(int i=0;i<n;i++) dis[i]=0;  
        while(1){  
            for(int i=0;i<n;i++) cur[i]=head[i];  
            while(1){  
                for(int i=0;i<n;i++) vis[i]=false;  
                int tmp=aug(ss,INF);  
                if(tmp==0) break;
                max_flow+=tmp;  
                min_cost+=tmp*dis[ss];  
            }  
            if(!modify_label()) break;  
        }  
        return mp( max_flow , min_cost );
    }
}solver;

int N , A , B ;
int TA = N + 1 , TB = N + 2 , T = N + 3 , S =0 ;
vector < int > idx[ 6500 ];

int main( int argc , char * argv[] ){
    //freopen("in.txt","r",stdin);
    N=read(),A=read(),B=read();
    TA = N + 1 , TB = N + 2 , T = N + 3 , S = 0;
    solver.init( N + 50 );
    solver.addedge( TA , T , A , 0);
    solver.addedge( TB , T , B , 0);
    rep(i,1,N){
        solver.addedge( S , i , 1 , 0 );
        int tp = read() , w = read();
        if( tp == 1 ) idx[i].pb(solver.addedge( i , TA , 1 , w ));
        else if( tp == 2 ) idx[i].pb(solver.addedge( i , TB , 1 , w ));
        else{
            idx[i].pb(solver.addedge( i , TA , 1 , w ));
            idx[i].pb(solver.addedge( i , TB , 1 , w ));
        }
    }
    pair < int , int > ans = solver.mincostmaxflow( S , T , N + 50 );
    pf("%d %d\n" , ans.first , ans.second );
    int fa = 0 , fb = A;
    for(int i = 1 ; i <= N ; ++ i){
        int targetv = -1;
        for(auto it : idx[i]){
            //cout << solver.edge[it].flow << endl;
            if( solver.edge[it].flow == 1 ){
                targetv = solver.edge[it].to;
                break;
            }
        }
        if( targetv == TA ) pf("%d %d\n" , i , ++ fa );
        else if( targetv == TB ) pf("%d %d\n" , i , ++ fb );
    }
    return 0;
}
    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/5775343.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞