您的位置:首页 > 编程语言 > Go语言

UVA 11090 Going in Cycle!! SPFA判断负圈

2016-08-17 17:09 246 查看
You are given a weighted directed graph with n vertices and m edges. Each cycle in the graph has a

weight, which equals to sum of its edges. There are so many cycles in the graph with different weights.

In this problem we want to find a cycle with the minimum mean.

Input

The first line of input gives the number of cases, N. N test cases follow. Each one starts with two

numbers n and m. m lines follow, each has three positive number a, b, c which means there is an edge

from vertex a to b with weight of c.

Output

For each test case output one line containing Case #x: followed by a number that is the lowest mean

cycle in graph with 2 digits after decimal place, if there is a cycle. Otherwise print No cycle found..

Constraints

• n ≤ 50

• a, b ≤ n

• c ≤ 10000000

Sample Input

2

2 1

1 2 1

2 2

1 2 2

2 1 3

Sample Output

Case #1: No cycle found.

Case #2: 2.50

//二分搜索答案 判断是否有负环
//假设存在一个有k条边的回路,平均值小于mid.
//则w1+w2+...+wk<k*mid
//即(w1-mid)+(w2-mid)+...+(wk-mid)<0
//转化为是否存在负环的问题,二分求解.

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<stack>
#include<set>
#include<bitset>
using namespace std;
const int INF=0x3f3f3f3f;
const double MIN=0.0001;
const int MAXN=55;
const int MAXM=MAXN*MAXN;
int T,N,M,E,a,b,c,MaxW;
int V[MAXM],Next[MAXM],First[MAXN],Cnt[MAXN];
double Dis[MAXN],W[MAXM];
bool Inque[MAXN];
void Init()
{
E=MaxW=0;
memset(First,-1,sizeof(First));
memset(Next,-1,sizeof(Next));
}
void AddEdge(int a,int b,int c)
{
V[E]=b;
Next[E]=First[a];
W[E]=c;
First[a]=E++;
}
bool NegativeCycle()
{
memset(Inque,false,sizeof(Inque));
memset(Cnt,0,sizeof(Cnt));
queue<int> que;
for (int i=1;i<=N;i++)
{
que.push(i);
Dis[i]=0;
}
while (!que.empty())
{
int u=que.front();
que.pop();
Inque[u]=false;
for (int i=First[u];i!=-1;i=Next[i])
{
if (Dis[V[i]]>Dis[u]+W[i])
{
Dis[V[i]]=Dis[u]+W[i];
if (!Inque[V[i]])
{
que.push(V[i]),Inque[V[i]]=true;
if (++Cnt[V[i]]>N)
return true;
}
}
}
}
return false;
}
bool Test(double x)
{
bool flag;
for (int i=0;i<E;i++)
W[i]-=x;
flag=NegativeCycle();
for (int i=0;i<E;i++)
W[i]+=x;
return flag;
}
int main()
{
scanf("%d",&T);
for (int cases=1;cases<=T;cases++)
{
Init();
scanf("%d%d",&N,&M);
for (int i=0;i<M;i++)
{
scanf("%d%d%d",&a,&b,&c);
MaxW=max(MaxW,c);
AddEdge(a,b,c);
}
double low=0,mid,high=MaxW;
if (!Test(high+1))
{
printf("Case #%d: No cycle found.\n",cases);
continue;
}
while (high-low>MIN)
{
mid=(low+high)/2;
if (Test(mid))
high=mid;
else
low=mid;
}
printf("Case #%d: %.2f\n",cases,high);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: