UVa11478 - Halum

来源:互联网 发布:如何精通三坐标编程 编辑:程序博客网 时间:2024/05/23 15:03

这里写图片描述

#include<iostream>#include<string>#include<cstring>#include<sstream>#include<vector>#include<algorithm>#include<queue>#include<cstdio>using namespace std;const int maxn=3000+10;const int INF=100000000;struct Edge{    int from,to,dist;    Edge(int u,int v,int d):from(u),to(v),dist(d){}};struct BellmanFord{    int n,m;    vector<Edge>edges;    vector<int>G[maxn];    int p[maxn];    int d[maxn];    int inq[maxn];    int cnt[maxn];    void init(int n){        this->n=n;        edges.clear();        for(int i=0;i<n;i++)G[i].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(){        queue<int>q;        memset(inq,0,sizeof(inq));        memset(cnt,0,sizeof(cnt));        for(int i=0;i<n;i++){d[i]=0;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){                    d[e.to]=d[u]+e.dist;                    p[e.to]=G[u][i];                    if(!inq[e.to]){                        q.push(e.to);inq[e.to]=1;                        if(++cnt[e.to]>n)return false;                    }                }            }        }        return true;    }};BellmanFord solver;bool test(int x){    for(int i=0;i<solver.m;i++)        solver.edges[i].dist-=x;    bool ret=solver.negativeCycle();    for(int i=0;i<solver.m;i++)        solver.edges[i].dist+=x;    return ret;}int n,m;int main(){  while(scanf("%d%d",&n,&m)==2){      solver.init(n);      int u,v,d;      int ud=0;      for(int i=0;i<m;i++){          scanf("%d%d%d",&u,&v,&d);ud=max(ud,d);          u--;v--;          solver.AddEdge(u,v,d);      }     if(test(ud+1))printf("Infinite\n"); // 如果可以让每条边权都>ub,说明每条边的权都增加了,重复一次会增加得更多...直到无限     else if(!test(1))printf("No Solution\n");     else{         int L=2,R=ud,ans=1;         while(L<=R){             int mid=(L+R)/2;             if(test(mid)){ans=mid;L=mid+1;}             else R=mid-1;        }        printf("%d\n",ans);        }    }  return 0;}
0 0