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 |
|||
Problem Setter: Md. Mahbubul Hasan |
思路:设sum(u)是u点所有加减操作的和,那么u->v的最终权值就是sum(u)+w(u,v)-sum(v)
二分最小权值x
那么就是 sum(u)+w(u,v)-sum(v)>=x
sum(v)<=sum(u)+w(u,v)-x 等价于最短路的d[v]<=d[u]+w(u,v);
因此一个差分就可以解决了。
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<algorithm> using namespace std; const int mm=500+9; const int mn=4700+9; const int oo=1e9; int n,m,edge; int head[mm]; class node { public:int v,next,dis; }e[mn]; void data() { memset(head,-1,sizeof(head));edge=0; } void add(int u,int v,int _dis) { e[edge].v=v;e[edge].dis=_dis;e[edge].next=head[u];head[u]=edge++; } int id[mm],dis[mm];bool vis[mm]; bool spfa(int x) { int u,v; memset(vis,0,sizeof(vis)); memset(id,0,sizeof(id)); queue<int>Q; for(int i=0;i<=n;++i) dis[i]=oo; Q.push(0);vis[0]=1; dis[0]=0; int z,spend; while(!Q.empty()) { u=Q.front();Q.pop();vis[u]=0; for(int i=head[u];~i;i=e[i].next) { v=e[i].v; spend=e[i].dis-x; if(dis[v]>dis[u]+spend) { dis[v]=dis[u]+spend; if(!vis[v]) { if(++id[v]>=n+1) {return 0;} vis[v]=1;Q.push(v); } } } } return 1; } int main() { int a,b,c; while(~scanf("%d%d",&n,&m)) { data(); for(int i=0;i<m;++i) { scanf("%d%d%d",&a,&b,&c); add(a,b,c); } for(int i=1;i<=n;++i) add(0,i,0); int l=0,r=10001,mid,ans=0; if(spfa(r)){printf("Infinite\n");continue;} if(!spfa(1)){printf("No Solution\n");continue;} while(l<=r) { mid=(l+r)/2; if(spfa(mid)){l=mid+1;ans=max(ans,mid);} else r=mid-1; } printf("%d\n",ans); } return 0; }