POJ 3621 Sightseeing Cows [最优比率环]

感觉去年9月的自己好$naive$ http://www.cnblogs.com/candy99/p/5868948.html

现在不也是嘛


 

裸题,具体看学习笔记

二分答案之后判负环就行了

$dfs$版超快

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int N=1005,M=5005;
const double eps=1e-4;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m,u,v;
double f[N];
struct edge{
    int v,ne;
    double w;
}e[M<<1];
int h[N],cnt=0;
inline void ins(int u,int v,int w){
    cnt++;
    e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
}
double d[N];
int inq[N],num[N];
int q[N],head,tail;
inline void lop(int &x){if(x==N) x=1;}
bool NegativeCircle(double mid){
    head=tail=0;
    for(int i=1;i<=n;i++) d[i]=0,inq[i]=1,q[tail++]=i,num[i]=1;
    while(head!=tail){
        int u=q[head++];lop(head);inq[u]=0;
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;double w=mid*e[i].w-f[u];
            if(d[v]>d[u]+w){
                d[v]=d[u]+w;
                if(!inq[v]){
                    inq[v]=1;q[tail++]=v;lop(tail);
                    if(++num[v]>n) return true;
                }
            }
        }
    }
    return false;
}
inline bool check(double mid){return NegativeCircle(mid);}
void solve(){
    double l=0,r=2000;
    while(r-l>eps){
        double mid=(l+r)/2.0;
        if(check(mid)) l=mid;
        else r=mid;
    }
    printf("%.2f",l);
}
int main(){
    freopen("in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=n;i++) f[i]=read();
    for(int i=1;i<=m;i++) u=read(),v=read(),ins(u,v,read());
    solve();
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int N=1005,M=5005;
const double eps=1e-4;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m,u,v;
double f[N];
struct edge{
    int v,ne;
    double w;
}e[M<<1];
int h[N],cnt=0;
inline void ins(int u,int v,int w){
    cnt++;
    e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
}
double d[N];
int vis[N],cl;
bool dfs(int u,double mid){
    vis[u]=cl;
    for(int i=h[u];i;i=e[i].ne){
        int v=e[i].v;double w=mid*e[i].w-f[u];
        if(d[v]>d[u]+w){
            d[v]=d[u]+w;
            if(vis[v]==vis[u]) return true;
            else if(dfs(v,mid)) return true;
        }
    }
    vis[u]=0;
    return false;
}
bool NegativeCircle(double mid){
    memset(vis,0,sizeof(vis));
    for(cl=1;cl<=n;cl++) if(dfs(cl,mid)) return true;
    return false;
}
inline bool check(double mid){return NegativeCircle(mid);}
void solve(){
    double l=0,r=2000;
    while(r-l>eps){
        double mid=(l+r)/2.0;
        if(check(mid)) l=mid;
        else r=mid;
    }
    printf("%.2f",l);
}
int main(){
    freopen("in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=n;i++) f[i]=read();
    for(int i=1;i<=m;i++) u=read(),v=read(),ins(u,v,read());
    solve();
}

 

posted @ 2017-02-22 23:26  Candy?  阅读(375)  评论(0编辑  收藏  举报