zoukankan      html  css  js  c++  java
  • 带权有向图求点数最少正环

    题意:

      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
    "); 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
    ");
        printf("%d
    ",ans);
    }
    
    Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.
  • 相关阅读:
    C# winform开发:Graphics、pictureBox同时画多个矩形
    C# “配置系统未能初始化” 异常解决
    Google Maps API V3 之 路线服务
    Google Maps API V3 之 图层
    Google Maps API V3 之绘图库 信息窗口
    Google 地图 API V3 之 叠加层
    驱动开发之libusb函数
    libusb的使用教程和例子
    libusb检测U盘插入
    使用libusb检测USB设备插拔状态
  • 原文地址:https://www.cnblogs.com/YCuangWhen/p/5255319.html
Copyright © 2011-2022 走看看