zoukankan      html  css  js  c++  java
  • BZOJ:1927: [Sdoi2010]星际竞速

    题解:最小费用流+二分图模型;

    左边表示出这个点,右边表示入这个点;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int maxn=10009;
    const int inf=1000000000;
    
    int n,m;
    int a[maxn];
    struct Edge{
    	int from,to,cap,flow,cost;
    };
    vector<int>G[maxn];
    vector<Edge>edges;
    int addedge(int x,int y,int z,int w){
    	Edge e;
    	e.from=x;e.to=y;e.cap=z;e.flow=0;e.cost=w;
    	edges.push_back(e);
    	e.from=y;e.to=x;e.cap=0;e.flow=0;e.cost=-w;
    	edges.push_back(e);
    	int c=edges.size();
    	G[x].push_back(c-2);
    	G[y].push_back(c-1);
    }
    
    int s,t,totn;
    queue<int>q;
    int inq[maxn];
    int d[maxn];
    int p[maxn];
    int Spfa(int &nowflow,int &nowcost){
    	for(int i=1;i<=totn;++i){
    		d[i]=inf;inq[i]=0;
    	}
    	q.push(s);inq[s]=1;d[s]=0;p[s]=0;
    	while(!q.empty()){
    		int x=q.front();q.pop();inq[x]=0;
    		for(int i=0;i<G[x].size();++i){
    			Edge e=edges[G[x][i]];
    			if(e.cap>e.flow&&d[x]+e.cost<d[e.to]){
    				d[e.to]=d[x]+e.cost;
    				p[e.to]=G[x][i];
    				if(!inq[e.to]){
    					q.push(e.to);
    					inq[e.to]=1;
    				}
    			}
    		}
    	}
    	
    	if(d[t]==inf)return 0;
    	int f=inf,x=t;
    	while(x!=s){
    		Edge e=edges[p[x]];
    		f=min(f,e.cap-e.flow);
    		x=e.from;
    	}
    	nowflow+=f;nowcost+=f*d[t];
    	x=t;
    	while(x!=s){
    		edges[p[x]].flow+=f;
    		edges[p[x]^1].flow-=f;
    		x=edges[p[x]].from;
    	}
    	return 1;
    }
    
    int Mcmf(){
    	int flow=0,cost=0;
    	while(Spfa(flow,cost));
    	return cost;
    }
    
    int minit(){
    	edges.clear();
    	for(int i=1;i<=totn;++i)G[i].clear();
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	s=n+n+1;t=totn=s+1;minit();
    	
    	for(int i=1;i<=n;++i){
    		scanf("%d",&a[i]);
    		addedge(s,i+n,1,a[i]);
    	}
    	for(int i=1;i<=m;++i){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		if(x>y)swap(x,y);
    		addedge(x,n+y,1,z);
    	}
    	for(int i=1;i<=n;++i){
    		addedge(s,i,1,0);
    		addedge(i+n,t,1,0);
    	}
    	printf("%d
    ",Mcmf());
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    Mongodb在Linux下的安装和启动和配置
    Java线程--Exchanger使用
    Java线程--Phaser使用
    Java线程--CyclicBarrier使用
    Java线程--CountDownLatch使用
    Java线程状态介绍
    Java8 Stream 的一些操作和介绍
    Java正则
    Linux curl命令进行网络请求
    Netty入门使用教程
  • 原文地址:https://www.cnblogs.com/zzyer/p/8179163.html
Copyright © 2011-2022 走看看