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

UVA 11090(p333)----Going in Cycle!!

2016-03-06 22:10 429 查看
#include<bits/stdc++.h>
#define debu
using namespace std;
const int maxn=100;
struct Edge
{
int from,to;
double dist;
};
struct BellmanFord
{
int n,m;
vector<Edge> edges;
vector<int> G[maxn];
bool inq[maxn];
double d[maxn];
int p[maxn];
int cnt[maxn];
void init(int n)
{
this->n=n;
for(int i=0; i<n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,double 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.0;
inq[0]=true;
q.push(i);
}
while(!q.empty())
{
int u=q.front();
q.pop();
inq[u]=false;
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]=true;
if(++cnt[e.to]>n)
return true;
}
}
}
}
return false;
}
};
int n,m;
double maxw;
BellmanFord ans;
int check(double val)
{
int flag=0;
for(int i=0; i<m; i++)
ans.edges[i].dist-=val;
if(ans.negativeCycle()) flag=1;
for(int i=0; i<m; i++)
ans.edges[i].dist+=val;
return flag;
}
double solve()
{
double mid;
double l=0.0,r=maxw;
if(!check(maxw+1)) return -1;
while(r-l>1e-4)
{
mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
//cout<<l<<" "<<r<<endl;
}
//cout<<l<<" "<<mid<<" "<<r<<endl;
return l;
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif // debug
int t,cas=0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
maxw=0.0;
ans.init(n);
for(int i=0; i<m; i++)
{
int x,y;
double w;
scanf("%d%d%lf",&x,&y,&w);
x--;y--;
ans.AddEdge(x,y,w);
maxw=max(maxw,w);
}
double ans=solve();
if(ans==-1) printf("Case #%d: No cycle found.\n",++cas);
else printf("Case #%d: %.2f\n",++cas,ans);
}
return 0;
}

题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2031

题解:二分答案。原题可化为是否存在一个平均权值小于ave的回路,即w[1]+w[2]+......+w[k]<k*ave,也即(w[1]-ave)+(w[2]-ave)+.......+(w[k]-ave)<0。所以将各边权值每次减去ave,判断是否存在负环,若存在则该ave合法,继续二分求最小值。(注意当不存在环时,即使将每条边权值减去max{w}+1也不可能形成负环)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: