zoukankan      html  css  js  c++  java
  • I

    - 题目大意

        可以给每个点的入边加一个值和出边加一个值,问最小的边权最大是多少。

    - 解题思路

        根据题目的描述,可以列出一个不等式d(a,b) +x(a)-x(b)>=m,移项可得x(b)-x(a)<=d(a,b)-m正好满足差分约束的形式。所有的边就对应着一个差分约束系统。差分约束有解的充要条件是不存在负环。然后利用SPFA和二分法来查找即可。

    - 代码

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<cstring>
    using namespace std;
    const int N = 1e3;
    const int M = 1e6 + 5;
    const int INF = 0x3f3f3f;
    int n, m;
    struct edge {
    	int v, next, w;
    }e[M * 2];
    int head[N], cnt;
    int d[N];
    int inq[N];
    int cn[N];
    void addedge(int u, int v, int c)
    {
    	e[cnt].w = c;
    	e[cnt].v = v;
    	e[cnt].next = head[u];
    	head[u] = cnt++;
    }
    bool SPFA(int s) {
    	memset(d, INF, sizeof(d));
    	memset(inq, 0, sizeof(inq));
    	memset(cn, 0, sizeof(cn));
    	queue<int> Q;
    	Q.push(s);
    	d[s] = 0;
    	inq[s] = 1;
    	cn[s]++;
    	while (Q.size()) {
    		int u = Q.front();
    		Q.pop();
    		inq[u] = 0;
    		for (int i = head[u]; ~i; i = e[i].next)
    		{
    			int v = e[i].v;
    			int w = e[i].w;
    			if (d[v] > d[u] + w)
    			{
    				d[v] = d[u] + w;
    				if (!inq[v])
    				{
    					Q.push(v);
    					inq[v] = 1;
    					if (++cn[v] >= n+1)
    						return false;
    				}
    			}
    		}
    	}
    	return true;
    }
    
    bool check(int x)
    {
    	bool vis = true;
    	for (int i = 0; i <= n; i++)
    	{
    		for (int j = head[i]; j != -1; j = e[j].next)
    			e[j].w -= x;
    	}
    	if (!SPFA(0))
    		vis = false;
    	for (int i = 0; i <= n; i++)
    	{
    		for (int j = head[i]; j != -1; j = e[j].next)
    			e[j].w += x;
    	}
    	return vis;
    }
    
    int main()
    {
    	int a, b, c;
    	while(~scanf("%d%d", &n, &m))
        {
        int sum = 1;
    	cnt = 0;
    	memset(head, -1, sizeof(head));
    	int l = 1, r = -INF, mid;
    
    	for (int i = 0; i < m; i++)
    	{
    		scanf("%d%d%d", &a, &b, &c);
    		addedge(a, b, c);
    		r = max(r, c);
    	}
    	for (int i = 1; i <= n; i++)
    		addedge(0, i, 0);
    	if (check(r + 1))
    	{
    		printf("Infinite
    ");
    		continue;
    	}
    	else if (!check(1))
    	{
    		printf("No Solution
    ");
    		continue;
    	}
    	else
    	{
    		while (r - l >= 0)
    		{
    			mid = (r + l) / 2;
    			if (check(mid))
    			{
    				l = mid + 1;
    				sum = mid;
    			}
    			else
    			{
    				r = mid - 1;
    			}
    		}
    	}
    	printf("%d
    ", sum);
        }
    	return 0;
    }
    

      

  • 相关阅读:
    大二实习使用的技术汇总(下)
    【JSP】JSTL使用core标签总结(不断更新中)
    凸包---HDU 2202
    poj
    [MFC]MFC中OnDraw与OnPaint的区别
    PHP 自动生成导航网址的最佳方法 v20130826
    汉语-词语-调料:百科
    汉语-词语-味觉:百科
    汉语-词语-本源:百科
    un-人物-企业家-迈纳·基思:百科
  • 原文地址:https://www.cnblogs.com/alpacadh/p/8523335.html
Copyright © 2011-2022 走看看