带权有向图求点数最少正环

题意:

  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);
}

 

转载于:https://www.cnblogs.com/YCuangWhen/p/5255319.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值