二分答案 若存在负圈则说明答案可以更优 dfs版spfa判负圈
1 #include<bits/stdc++.h> 2 #define clr(a,x) memset(a,x,sizeof(a)) 3 #define rep(i,l,r) for(int i=l;i<r;i++) 4 typedef long long ll; 5 using namespace std; 6 int read() 7 { 8 char c=getchar(); 9 int ans1=0,f=1; 10 while(!isdigit(c)){ 11 if(c=='-') f=-1; 12 c=getchar(); 13 } 14 while(isdigit(c)){ 15 ans1=ans1*10+c-'0'; 16 c=getchar(); 17 } 18 return ans1*f; 19 } 20 struct edge{ 21 int to;double d,v; 22 }; 23 const double esp=1e-9,inf=1e7; 24 const int maxn=3005; 25 int n,m; 26 double d[maxn]; 27 bool p[maxn],flag; 28 vector<edge>e[maxn]; 29 void dfs(int a) 30 { 31 p[a]=1; 32 rep(i,0,e[a].size()){ 33 if(d[a]+e[a][i].v<d[e[a][i].to]) 34 { 35 if(!p[e[a][i].to]){ 36 d[e[a][i].to]=d[a]+e[a][i].v; 37 dfs(e[a][i].to); 38 }else flag=1; 39 if(flag){ 40 p[a]=0; 41 return; 42 } 43 } 44 } 45 p[a]=0; 46 } 47 bool ok(double a) 48 { 49 clr(p,0),clr(d,0),flag=0; 50 rep(i,1,n+1){ 51 rep(j,0,e[i].size()){ 52 e[i][j].v=e[i][j].d-a; 53 } 54 } 55 rep(i,1,n+1){ 56 dfs(i); 57 if(flag) return 1; 58 } 59 return 0; 60 } 61 double find(double l,double r) 62 { 63 if(r-l<=esp) return l; 64 double mid=(l+r)/2; 65 return ok(mid)?find(l,mid):find(mid,r); 66 } 67 int main() 68 { 69 n=read(),m=read(); 70 rep(i,0,m){ 71 int from=read(); 72 edge ed; 73 ed.to=read(); 74 scanf("%lf",&ed.d); 75 e[from].push_back(ed); 76 } 77 printf("%.8lf ",find(-inf,inf)); 78 return 0; 79 }
1486: [HNOI2009]最小圈
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1448 Solved: 680
[Submit][Status][Discuss]