• UVA 11090 Going in Cycle!!(Bellman-Ford推断负圈)


    题意:给定一个n个点m条边的加权有向图,求平均权值最小的回路。

    思路:使用二分法求解。对于每个枚举值mid,推断每条边权值减去mid后有无负圈就可以。

    #include<cstdio>  
    #include<cstring>  
    #include<cmath>  
    #include<cstdlib>  
    #include<iostream>  
    #include<algorithm>  
    #include<vector>  
    #include<map>  
    #include<queue>  
    #include<stack> 
    #include<string>
    #include<map> 
    #include<set>
    #define eps 1e-4 
    #define LL long long  
    using namespace std;  
    
    const int maxn = 100 + 5;
    const int INF = 0x3f3f3f3f;
    
    //Bellman-Ford算法
    struct Edge {
    	int from, to;
    	double dist;
    	Edge(int u = 0, int v = 0, double d = 0) : from(u), to(v), dist(d) {
    	}
    };
    struct BellmanFord{
    	int n, m;
    	vector<Edge> edges;
    	vector<int> G[maxn];
    	bool inq[maxn];
    	double d[maxn];
    	int p[maxn];
    	int cnt[maxn];
    	
    	void init(int n) {
    		this->n = n;
    		for(int i = 0; i < n; i++) G[i].clear();
    		edges.clear();
    	}
    	
    	void AddEdges(int from, int to, int dist) {
    		edges.push_back(Edge(from, to, dist));
    		m = edges.size();
    		G[from].push_back(m-1);
    	}
    	
    	bool negetiveCycle() {
    		queue<int> Q;
    		memset(inq, 0, sizeof(inq));
    		memset(cnt, 0, sizeof(cnt));
    		for(int i = 0; i < n; i++) {
    			d[i] = 0; inq[0] = true; Q.push(i);
    		}
    		while(!Q.empty()) {
    			int u = Q.front(); Q.pop();
    			inq[u] = false;
    			for(int i = 0; i < G[u].size(); i++) {
    				Edge& e = edges[G[u][i]];
    				if(d[e.to]>d[u]+e.dist) {
    					d[e.to] = d[u] + e.dist;
    					p[e.to] = G[u][i];
    					if(!inq[e.to]) {
    						Q.push(e.to);
    						inq[e.to] = true;
    						if(++cnt[e.to] > n) return true;
    					}
    				}
    			}
    		}
    		return false;
    	}
    	
    } solver; 
    
    int n, m;
    bool test(double w) {
    	for(int i = 0; i < m; i++) solver.edges[i].dist -= w;
    	int t = solver.negetiveCycle();
    	for(int i = 0; i < m; i++) solver.edges[i].dist += w;
    	return t;
    }
    
    int kase;
    int main() {
    	freopen("input.txt", "r", stdin);
    	int t; cin >> t;
    	while(t--) {
    		cin >> n >> m;
    		solver.init(n);
    		for(int i = 0; i < m; i++) {
    			int u, v, d;
    			cin >> u >> v >> d;
    			u--; v--;
    			solver.AddEdges(u, v, d);
    		}
    		double L = -10000001, R = 10000001;
    		if(!test(R)) printf("Case #%d: No cycle found.
    ", ++kase);
    		else {
    			while(R-L>eps) {
    				double M = (R+L)/2;
    				if(test(M)) R = M;
    				else L = M;
    			}
    			printf("Case #%d: %.2lf
    ", ++kase, R);
    		}
    	}
    	return 0;
    }
    
    
    
    
    

  • 相关阅读:
    Docker学习笔记之一,搭建一个JAVA Tomcat运行环境
    利用Docker构建开发环境
    MyEclipse 8.6.1 制作绿色版
    Tomcat,JBoss与JBoss Web
    oracle,mysql,SqlServer三种数据库的分页查询
    Tomcat+JSP经典配置实例
    [转载]JDK自带的实用工具——native2ascii.exe
    用sql删除数据库重复的数据的方法
    Dom4j 使用简介(全而好的文章)
    Java操作XML文件 dom4j 篇
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6994628.html
Copyright © 2020-2023  润新知