標籤:des style http color os width
Description
| |
Problem H |
Halum |
Time Limit : 3 seconds |
|
| |
You are given a directed graph G(V,E) with a set of vertices and edges. Each edge (i,j) that connects some vertex i to vertex j has an integer cost associated with that edge. Define the operation Halum(v, d) to operate on a vertex v using an integer d as follows: subtract d from the cost of all edges that enter v and add d to the cost of every edge that leaves v.
As an example of that operation, consider graph G that has three vertices named (1, 2, 3) and two edges. Edge (1, 2) has cost -1, and edge (2,3) has cost 1. The operation Halum(2,-3) operates on edges entering and leaving vertex 2. Thus, edge (1, 2) gets cost -1-(-3)=2 and the edge (2, 3) gets cost 1 + (-3) = -2. Your goal is to apply the Halum function to a graph, potentially repeatedly, until every edge in the graph has at least a certain cost that is greater than zero. You have to maximize this cost. |
|
| |
Input |
|
|
| |
Two space-separated integers per case: V(V≤500) andE(E≤2700). E lines follow. Each line represents a directed edge using three space-separated integers (u, v, d). Absolute value of cost can be at most 10000. |
|
| |
|
|
| |
Output |
|
| |
If the problem is solvable, then print the maximum possible value. If there is no such solution print “No Solution”. If the value can be arbitrary large print “Infinite” |
|
| |
|
|
| |
Sample Input |
Sample Output |
|
|
| |
2 1 1 2 10 2 1 1 2 -10 3 3 1 2 4 2 3 2 3 1 5 4 5 2 3 4 4 2 5 3 4 2 3 1 0 1 2 -1
|
Infinite Infinite 3 1
|
題意:給定一個有向圖,每條邊都有一個權值,每次你可選擇一個結點v和一個整數d,把所有以v為終點的邊的權值減少d,把所有以v為終點的邊的權值增加d,最後要讓所有邊的最小值非負且盡量大。
思路:最小值最大,很顯然想到二分答案,可以令sum(u)表示為作用在節點u之上的所有d之和,這樣題目的目標就是確定所有的sum(u)了; 對於邊a->b,不難發現操作後的權值是:w(a, b)+sum(a)-sum(b)>=x
那麼就可以得到個不等式:sum(b)-sum(a) <= w(a, b)-x,而w(a, b)-x我們是已知的,那麼就能得到相當於最短路的
不等式 d[v]<=d[u]+w(u, v),那麼我們就可以構建一個新圖,那麼我們在做Bellman-Ford的時候,如果發現負權環的話,那麼就相當於我們無法得到一個類似最短路的不等式,所有無解
#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <queue>#include <vector>using namespace std;const int maxn = 505;const int inf = 0x3f3f3f3f;struct Edge {int from, to, dist;};struct BellmanFord {int n, m;vector<Edge> edges;vector<int> G[maxn];int inq[maxn];int 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 AddEdge(int from, int to, int dist) {edges.push_back((Edge){from, to, dist});m = edges.size();G[from].push_back(m-1);}bool negativeCycle(int tmp) {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] = 1;Q.push(i);}while (!Q.empty()) {int u = Q.front();Q.pop();inq[u] = 0;for (int i = 0; i < G[u].size(); i++) {Edge &e = edges[G[u][i]];if (d[e.to] > d[u] + e.dist - tmp) {d[e.to] = d[u] + e.dist - tmp;p[e.to] = G[u][i];if (!inq[e.to]) {Q.push(e.to);inq[e.to] = 1;if (++cnt[e.to] > n)return 1;}}}}return 0;}};BellmanFord solve;int n, m;int main() {int u, v, w;while (scanf("%d%d", &n, &m) != EOF) {solve.init(n);int l = 1, r = 0, mid;for (int i = 0; i < m; i++) {scanf("%d%d%d", &u, &v, &w);u--, v--;solve.AddEdge(u, v, w);r = max(r, w);}if (solve.negativeCycle(1))printf("No Solution\n");else if (!solve.negativeCycle(r+1))printf("Infinite\n");else {while (l < r) {mid = l + (r-l+1)/2;if (solve.negativeCycle(mid))r = mid-1;else l = mid;}printf("%d\n", l);}}return 0;}