• HDU 4309 Contest 1


    最大流建图。开始以为旧桥有1000座,没敢用枚举,后来看看题目发现了只是十二座。枚举桥的状态没问题。

    对于隧道的容量W,可以虚拟出第三个结点表示,如u->v。增加一个点p,u->p(INF),p->v(INF),p->End(W);

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int MAXN=300;//点数的最大值
    const int MAXM=5000;//边数的最大值
    
    struct Node{
        int from,to,next;
        int cap;
    }edge[MAXM];
    
    struct Edge{
    	int u,v,w;
    }Tun[30],Acient[20],Modern[1000];
    
    int tol;
    int dep[MAXN];
    int head[MAXN];
    int val[MAXN];
    
    void init(){
        tol=0;
        memset(head,-1,sizeof(head));
    }
    void addedge(int u,int v,int w){
        edge[tol].from=u;
        edge[tol].to=v; edge[tol].cap=w;  edge[tol].next=head[u];
        head[u]=tol++;
        edge[tol].from=v;
        edge[tol].to=u;
        edge[tol].cap=0;
        edge[tol].next=head[v];
        head[v]=tol++;
    }
    
    int BFS(int start,int end){
        int que[MAXN];
        int front,rear; front=rear=0;
        memset(dep,-1,sizeof(dep));
        que[rear++]=start;
        dep[start]=0;
        while(front!=rear){
            int u=que[front++];
            if(front==MAXN)front=0;
            for(int i= head[u];i!=-1; i=edge[i].next){
                int v=edge[i].to;
                if(edge[i].cap>0&& dep[v]==-1){
                    dep[v]=dep[u]+1;
                    que[rear++]=v;
                    if(rear>=MAXN) rear=0;
                    if(v==end)return 1;
                }
            }
        }
        return 0;
    }
    
    int dinic(int start,int end){
        int res=0;
        int top;
        int stack[MAXN];
        int cur[MAXN];
        while(BFS(start,end)){
            memcpy(cur,head, sizeof(head));
            int u=start;
            top=0;
            while(1){
                if(u==end){
                    int min=INF;
                    int loc;
                   for(int i=0;i<top;i++)
                      if(min>edge [stack[i]].cap){
                          min=edge [stack[i]].cap;
                          loc=i;
                      }
                    for(int i=0;i<top;i++){
                        edge[stack[i]].cap-=min;
                        edge[stack[i]^1].cap+=min;
                    }
                    res+=min;         
                    top=loc;       
                    u=edge[stack[top]].from;
                }
                for(int i=cur[u]; i!=-1; cur[u]=i=edge[i].next)        
                  if(edge[i].cap!=0 && dep[u]+1==dep[edge[i].to])
                     break;
                if(cur[u] !=-1){
                    stack [top++]= cur[u];
                    u=edge[cur[u]].to;
                }
                else{
                    if(top==0) break;   
                    dep[u]=-1;
                    u= edge[stack [--top] ].from;   
                }
            }
        }
        return res;
    }
    
    int main(){
    	int n,e;
    	int nT,nA,nM;
    	int u,v,w,p;
    	while(scanf("%d%d",&n,&e)!=EOF){
    		nT=nA=nM=0;
    		for(int i=1;i<=n;i++)
    			scanf("%d",&val[i]);
    		for(int i=0;i<e;i++){
    			scanf("%d%d%d%d",&u,&v,&w,&p);
    			if(p==0){
    				Modern[nM].u=u;Modern[nM].v=v;
    				Modern[nM].w=w;
    				nM++;
    			}
    			else if(p<0){
    				Tun[nT].u=u;Tun[nT].v=v;
    				Tun[nT].w=w;
    				nT++;
    			}
    			else{
    				Acient[nA].u=u; Acient[nA].v=v;
    				Acient[nA].w=w;
    				nA++;
    			}
    		}
    		int Start=0,End;
    		End=n+nT+1;
    		int len=(1<<nA);
    		int cost,people,ansc=0,anspeople=0;
    		for(int i=0;i<len;i++){
    			init();
    			cost=0;
    			for(int k=1;k<=n;k++){
    				addedge(Start,k,val[k]);
    			}
    			for(int k=0;k<nA;k++){
    				if(i&(1<<k)){
    					addedge(Acient[k].u,Acient[k].v,INF);
    					cost+=Acient[k].w;
    				}
    				else 
    				addedge(Acient[k].u,Acient[k].v,1);
    			}
    			for(int k=0;k<nM;k++){
    				addedge(Modern[k].u,Modern[k].v,INF);
    			}
    			for(int k=0;k<nT;k++){	
    				addedge(Tun[k].u,n+k+1,INF);
    				addedge(n+k+1,Tun[k].v,INF);
    				addedge(n+k+1,End,Tun[k].w);
    			}
    		//	system("pause");
    			people=dinic(Start,End);
    			if(people>anspeople){
    				anspeople=people;
    				ansc=cost;
    			}
    			else if(people==anspeople){
    				ansc=min(cost,ansc);
    			}
    		}
    		if(anspeople==0){
    			printf("Poor Heaven Empire
    ");
    		}
    		else
    		printf("%d %d
    ",anspeople,ansc);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Java多线程之“同步”
    50 道 Java 线程面试题(转载自牛客网)
    Ubuntu14.04搭建Caffe(仅CPU)
    【译】OkHttp3 拦截器(Interceptor)
    OkHttp3 使用详解
    JSP ---- 声明、表达式、脚本、注释
    dom解析和sax解析的区别及优缺点
    一个java源文件中为什么只能有一个public类。
    js传入参数为字符串问题
    java project中 xml文件路径问题
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4050961.html
Copyright © 2020-2023  润新知