Problem H
|
Halum
|
Time Limit : 3 seconds
| ||
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) and E(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 | Infinite |
每个点是一个未知数,设a->b,cost=c,最小变得值为x(即答案)则:c+a-b >= x =》 b-a <= c-x,二分这个x得出答案。
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const int inf = 1000000000;
const int maxn = 520;
const int maxe = 15*maxn;
const int INF = 100000;
struct edge{
int u , v , c , next;
edge(int a = 0 , int b = 0 , int cost = 0 , int n = -1){
u = a, v = b , c = cost , next = n;
}
}e[maxe];
vector<edge> ini_e;
int V , E , cnt , head[maxn] , vis[maxn] , vt[maxn] , dis[maxn];
void add(int u , int v , int cost){
e[cnt] = edge(u , v , cost , head[u]);
head[u] = cnt++;
}
void init(){
cnt = 0;
for(int i = 0; i < maxn; i++){
vis[i] = 0;
vt[i] = 0;
head[i] = -1;
dis[i] = inf;
}
}
void initial(){
init();
ini_e.clear();
}
void readcase(){
int u , v , c;
for(int i = 0; i < E; i++){
scanf("%d%d%d" , &u , &v , &c);
ini_e.push_back(edge(u , v , c));
}
}
void build_graph(int m){
init();
for(int i = 1; i <= V; i++) add(0 , i , 0);
for(int i = 0; i < ini_e.size(); i++){
add(ini_e[i].u , ini_e[i].v , ini_e[i].c-m);
}
}
bool spfa(int start){
queue<int> q;
vis[start] = 1;
vt[start]=1;
dis[start] = 0;
q.push(start);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = 0;
if(vt[u] > sqrt(V*1.0)+1) return false;
for(int i = head[u]; i != -1; i = e[i].next){
int v = e[i].v;
int c = e[i].c;
if(dis[v] > dis[u]+c){
dis[v] = dis[u]+c;
if(!vis[v]){
vis[v] = 1;
vt[v]++;
q.push(v);
}
}
}
}
return true;
}
void computing(){
int l = 0 , r = INF;
while(l < r){
int mid = (l+r)/2;
//cout << l << " " << r << " " << mid << endl;
build_graph(mid);
if(spfa(0)) l = mid+1;
else r = mid;
}
if(l <= 1) printf("No Solution\n");
else if(l != INF) printf("%d\n" , l-1);
else printf("Infinite\n");
}
int main(){
while(~scanf("%d%d" , &V , &E)){
initial();
readcase();
computing();
}
return 0;
}