带权有向图求点数最少正环
题意:
RT
SOL:
图论啊...真是博大精深,这种题目看看像我以前做过的那个什么最小环覆盖,但是貌似又不能用上,网络流又套不上模型...那么就搜吧!
搜...搜也就是骗骗分...你能抱多大希望?于是打了一个找环的丝帛DFS交了上去.
然后最后没骗几分...然而打开高分代码...第一个难道不就是差不多的DFS加了一个二分答案? 跪吐血...
因为点数不多然后应该枚举每个点然后dfs....马丹我真是丝帛...
然后一个我觉得正确性不那么显然的优化----->当前权值和小于0就退出,这真是没怎么看懂...你看万一后来更大呢(貌似可以在其它点的DFS中考虑到)
马丹啊...真是丝帛啊...多想一点可能就不一样了...
跪翁神
Code:
//Orz wengyijia11!!!!! //Orz wengyijia11!!!!! //Orz wengyijia11!!!!! //Orz wengyijia11!!!!! //Orz wengyijia11!!!!! //Orz wengyijia11!!!!! /*========================================================================== # Last modified: 2016-03-08 11:08 # Filename: t2.cpp # Description: ==========================================================================*/ #define me AcrossTheSky #include <cstdio> #include <cmath> #include <ctime> #include <string> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <set> #include <map> #include <stack> #include <queue> #include <vector> #define lowbit(x) (x)&(-x) #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) #define FORP(i,a,b) for(int i=(a);i<=(b);i++) #define FORM(i,a,b) for(int i=(a);i>=(b);i--) #define ls(a,b) (((a)+(b)) << 1) #define rs(a,b) (((a)+(b)) >> 1) #define getlc(a) ch[(a)][0] #define getrc(a) ch[(a)][1] #define maxn 100000 #define maxm 100000 #define pi 3.1415926535898 #define _e 2.718281828459 #define INF 1070000000 using namespace std; typedef long long ll; typedef unsigned long long ull; template<class T> inline void read(T& num) { bool start=false,neg=false; char c; num=0; while((c=getchar())!=EOF) { if(c=='-') start=neg=true; else if(c>='0' && c<='9') { start=true; num=num*10+c-'0'; } else if(start) break; } if(neg) num=-num; } /*==================split line==================*/ struct Edge{ int to,v; }e[maxm]; int sume=0; int ans,n,m,cap; int vis[maxn],a[maxn],ct[maxn],first[maxn],next[maxm]; int dis[maxn]; void addedge(int x,int y,int z){ sume++; e[sume].to=y; e[sume].v=z; next[sume]=first[x]; first[x]=sume; } //int vis[maxn],a[maxn],ct[maxn]; bool dfs(int node,int cnt){//(int node,int sum,int cnt){ //vis[node]=-1;a[node]=sum; ct[node]=cnt; if (cnt>cap) return false; if (dis[node]<0) return 0; vis[node]=1; for (int i=first[node];i;i=next[i]) if(dis[e[i].to]<=dis[node]+e[i].v){ dis[e[i].to]=dis[node]+e[i].v; //int x=e[i].to; if (vis[e[i].to]==0) { if (dfs(e[i].to,cnt+1)) return true; } else return true; } vis[node]=0;/*else if (vis[x]==1) continue; else if (vis[x]==-1) { if (sum+e[i].v-a[x]>0) { if (cnt-ct[x]+1<ans) ans=cnt-ct[x]+1; } }*/ return false; //vis[node]=1; } int main(){ read(n); read(m); memset(first,0,sizeof(first)); FORP(i,1,m){ int x,y,z1,z2; read(x); read(y); read(z1); read(z2); if (z1+z2>0) {printf("2\n"); return 0;} addedge(x,y,z1); addedge(y,x,z2); } memset(vis,0,sizeof(vis)); //addedge(0,1,0); int l=3,r=n; ans=0; while (l<=r){ cap=(l+r)/2; bool flag=false; FORP(i,1,n){ memset(vis,0,sizeof(vis)); FORP(j,1,n) dis[j]=-INF; dis[i]=0; if (dfs(i,1)){ flag=true;break; } } if (flag){ ans=cap; r=cap-1; } else l=cap+1; } //if (ans==INF) printf("0\n"); printf("%d\n",ans); }
Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.