zoukankan      html  css  js  c++  java
  • A new Graph Game

    点击打开链接

    题意:给你一张N个节点的无向图。然后给出M条边,给出第 I 条边到第J条边的距离。然后问你是否存在子环,假设存在,则输出最成环的最短距离和

    解析:构图:选定源点及汇点,然后将源点至个点流量置为1,花费置为0.然后使用最小费用流,当返回值流量和,即flow < n 时。则输出NO。由于全部边成环最少边数为N。

    其余和tour一样求法。处理一下某两点距离为最短距离就可以。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    
    using namespace std;
    
    const int maxn = 10000;
    const int maxm = 100000;
    const int INF = 0xfffffff;
    
    struct Edge{
    	int to, next, cap, flow, cost;
    }edge[ maxm ];
    
    int head[ maxn ], tol;
    int pre[ maxn ], dis[ maxn ];
    bool vis[ maxn ];
    
    int N;
    
    void init( int n ){
    	N = n;
    	tol = 0;
    	memset( head, -1, sizeof( head ) );
    }
    
    void addedge( int u, int v, int cap, int cost ){
    	edge[ tol ].to = v;
    	edge[ tol ].cap = cap;
    	edge[ tol ].cost = cost;
    	edge[ tol ].flow = 0;
    	edge[ tol ].next = head[ u ];
    	head[ u ] = tol++;
    	edge[ tol ].to = u;
    	edge[ tol ].cap = 0;
    	edge[ tol ].cost = -cost;
    	edge[ tol ].flow = 0;
    	edge[ tol ].next = head[ v ];
    	head[ v ] = tol++;
    }
    
    bool spfa( int s, int t ){
    	queue< int > q;
    	for( int i = 0; i < N; ++i ){
    		dis[ i ] = INF;
    		vis[ i ] = false;
    		pre[ i ] = -1;
    	}
    	dis[ s ] = 0;
    	vis[ s ] = true;
    	q.push( s );
    	while( !q.empty( ) ){
    		int u = q.front();
    		q.pop();
    		vis[ u ] = false;
    		for( int i = head[ u ]; i != - 1; i = edge[ i ].next ){
    			int v = edge[ i ].to;
    			if( edge[ i ].cap > edge[ i ].flow && dis[ v ] > dis[ u ] + edge[ i ].cost ){
    				dis[ v ] = dis[ u ] + edge[ i ].cost;
    				pre[ v ] = i;
    				if( !vis[ v ] ){
    					vis[ v ] = true;
    					q.push( v );
    				}
    			}
    		}
    	}
    	if( pre[ t ] == -1 ) 
    		return false;
    	else
    		return true;
    }
    
    struct node{
    	int f, c;
    };
    
    //node a;
    node minCostMaxflow( int s, int t, int &cost ){
    	int flow = 0;
    	cost = 0;
    	while( spfa( s, t ) ){
    		int Min = INF;
    		for( int i = pre[ t ]; i != - 1; i = pre[ edge[ i ^ 1 ].to ] ){
    			if( Min > edge[ i ].cap - edge[ i ].flow )
    				Min = edge[ i ].cap - edge[ i ].flow;
    		}
    		for( int i = pre[ t ]; i  != -1; i = pre[ edge[ i ^ 1 ].to ] ){
    			edge[ i ].flow += Min;
    			edge[ i ^ 1 ].flow -= Min;
    			cost += edge[ i ].cost * Min;
    		}
    		flow += Min;
    	}
    	node ans;
    	ans.f = flow;
    	ans.c = cost;
    	return ans;
    }
    
    #define INF 0xfffffff
    int mapp[ maxn ][ maxn ];
    
    int main(){
    	int Case;
    	int n, m;
    	scanf( "%d", &Case );
    	for( int k = 1; k <= Case; ++k ){
    		scanf( "%d%d", &n, &m );
    		for( int i = 0; i <= n; ++i ){
    			for( int j = 0; j <= n; ++j ){
    				mapp[ i ][ j ] = INF;
    			}
    		}
    		int start = 0, end = 2 * n + 1, N = 2 * n + 2;
    		init( N );
    		int x, y, value;
    		for( int i = 1; i <= n; ++i ){
    			addedge( 0, i, 1, 0 );
    			addedge( n + i, end, 1, 0 );
    		}
    		int Max = 0;
    		for( int i = 0; i < m; ++i ){
    			scanf( "%d%d%d", &x, &y, &value );
    			int temp = max( x, y );
    			if( Max < temp ){
    				Max = temp;
    			}
    			if( mapp[ x ][ y ] > value ){
    				mapp[ x ][ y ] = mapp[ y ][ x ] = value;
    			}
    		}
    		
    		for( int i = 1; i <= n ; ++i ){
    			for( int j = 1; j <= n; ++j ){
    				if( mapp[ i ][ j ] != INF ){
    					addedge( i, n + j, 1, mapp[ i ][ j ] );
    				}
    			}
    		}
    		int cost;
    		node ans = minCostMaxflow( start, end, cost );
    		printf( "Case %d: ", k );
    		if( ans.f >= n ){	
    			printf( "%d
    ", ans.c );
    		}
    		else{
    			puts( "NO" );
    		}
    	} 
    	return 0;
    }


  • 相关阅读:
    并查集图冲突hdu1272
    CentOS 7通过yum安装fcitx五笔输入法
    近期的技术问题让云供应商进行预设加密
    POJ 1166 The Clocks (暴搜)
    windows中的mysql修改管理员密码
    Visio画UML类图、序列图 for Java
    js中的时间与毫秒数互相转换
    java.lang.OutOfMemoryError: unable to create new native thread 居然是MQ问题
    WEB移动应用框架构想(转载)
    Android SDK安装教程
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5231580.html
Copyright © 2011-2022 走看看