zoukankan      html  css  js  c++  java
  • 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
    " , 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
    " , i , ++ fa );
    		else if( targetv == TB ) pf("%d %d
    " , i , ++ fb );
    	}
    	return 0;
    }
  • 相关阅读:
    虚拟环境地址
    ubuntu 查看占用文件空间大小
    drf serializer官网所得
    百度api 找到当前电话号码归属地
    mongo 改bug
    django orm 读写分离,分库分app
    __setattr__,__getattr__,__getattribute__
    Python之路--Django--模型
    Python之路--Django--模板
    Python之路--Django--视图
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5775343.html
Copyright © 2011-2022 走看看