uva 11090 Going in Cycle!! 平均权值最小的回路

来源:互联网 发布:电脑数据库在哪里 编辑:程序博客网 时间:2024/05/30 07:12

题目:

https://uva.onlinejudge.org/external/110/11090.pdf


//by yskysker123int n,m;double ans;struct Edge{    int from,to;    double w;    Edge(){}    Edge(int from,int to,double w):from(from),to(to),w(w){}};vector<Edge>edges;vector<int >G[maxn];inline void add_edge(int x,int y,double w){    edges.push_back(Edge(x,y,w));    int m=edges.size();    G[x].push_back(m-1);}inline void init(){    edges.clear();    for(int i=1;i<=n;i++)    G[i].clear();}bool inq[maxn];int cnt[maxn];double d[maxn];bool SPFA(){     queue<int > q;     memset(inq, 0, sizeof(inq));    memset(cnt, 0, sizeof(cnt));    for(int i = 1; i <= n; i++)        { d[i] = 0; inq[0] = true; q.push(i); }    while(!q.empty())    {        int x=q.front();q.pop();        inq[x]=0;        for(int i=0;i<G[x].size();i++)        {            int id=G[x][i];            Edge &e=edges[id];            int y=e.to;            if( d[y]>d[x]+e.w )            {                d[y]=d[x]+e.w;                if( !inq[y])                {                    inq[y]=1;                    q.push(y);                    if(++cnt[y]>n)                        return true;                }            }        }    }    return false;}bool test(double del){       int m=edges.size();    for(int i=0;i<m;i++)    {        Edge &e=edges[i];        e.w-=del;    }    bool ret=SPFA();           for(int i=0;i<m;i++)    {        Edge &e=edges[i];        e.w+=del;    }    return ret;}int main(){  int T,kase=0;scanf("%d",&T);  int x,y;double  z;  while(T--)  {      scanf("%d%d",&n,&m);      init();      double t=0;      for(int i=1;i<=m;i++)      {          scanf("%d%d%lf",&x,&y,&z);          t=max(t,z);          add_edge(x,y,z);      }      printf("Case #%d: ",++kase);      if( !test(t+0.001))    //如果没有这一步,而直接在二分中判断有没有 mid使之存在负环的,那么wa,原因不明        puts("No cycle found.");        else     {       double le=0,ri=t;     double ans=t;   //之前把ans赋初值为INF,这样是不对的,如果二分范围太大 最后有些值可能满足判断条件,但是实际上不存在这种情况          while(ri-le>1e-5)          {              double mid=le + (ri-le)/2;              if(test(mid))              {                  ri=mid;                ans=min(ans,mid);              }              else le=mid;          }     printf("%.2lf\n", ans);    }  }    return 0;}


#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<climits>#include<queue>#include<vector>#include<map>#include<sstream>#include<set>#include<stack>#include<utility>#pragma comment(linker, "/STACK:102400000,102400000")#define PI 3.1415926535897932384626#define eps 1e-7#define sqr(x) ((x)*(x))#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)#define  lson   num<<1,le,mid#define rson    num<<1|1,mid+1,ri#define MID   int mid=(le+ri)>>1#define zero(x)((x>0? x:-x)<1e-15)#define mk    make_pair#define _f     first#define _s     secondusing namespace std;//const int INF=    ;typedef long long ll;const ll inf =1000000000000000;//1e15;//ifstream fin("input.txt");//ofstream fout("output.txt");//fin.close();//fout.close();//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);const int INF =0x3f3f3f3f;const int maxn=50+10    ;//const int maxm=    ;


0 0