zoukankan      html  css  js  c++  java
  • bzoj1064: [Noi2008]假面舞会

    莫名其妙的dfs算法。

    1.这道题首先要推出来,如果有弓形或者环形,答案必须是环长度和弓形俩条路长度之差的约数。

    而且如果你直接按照原图来建图你是跑不出来的。

    1.如果你每个点访问一次时dfs所有点,tle。

    2.如果你打vis标记,你判断不出来弓形,wa。

    3.如果妄图用一个in数组记录哪个点in[u]=0,然后从这个点开始跑的话。整体做个环,甩出去个头支的。wa+奇奇怪怪的错误。

    所以我们要求每个点逆向也可以跑。

    所以建图为 a->b 1,b->a->-1。

    这样上述问题就不会出现了。

    2.如果没有上述情况,肯定就是个dag图。跑dfs就行了。

    然后求最多可能有多少类面具的答案为sum(最长链的长度)。用心去感受

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    const int maxn = 100000 + 10;
    const int maxm = 4000000 + 10;
    const int inf = 0x3f3f3f3f;
    int g[maxn],v[maxm],next[maxm],dist[maxm],eid;
    int c[maxn];
    bool vis[maxn],inque[maxn],mark;
    int n,m,ans,l,r,minres,maxres,u;
    queue<int> q;
    
    void addedge(int a,int b,int c) {
        v[eid]=b; dist[eid]=c; next[eid]=g[a]; g[a]=eid++;    
    }
    
    int gcd(int a,int b) {
        return b==0?a:gcd(b,a%b);    
    }
    
    void dfs(int u,int fa,int d) {
        if(vis[u]) {
            ans=gcd(ans,abs(d-c[u]));
            return;
        }
        vis[u]=1;
        c[u]=d;
        for(int i=g[u];~i;i=next[i]) if(v[i]!=fa) dfs(v[i],u,c[u]+dist[i]);
    }
    
    void build() {
        memset(g,-1,sizeof(g));
        scanf("%d%d",&n,&m);
        for(int i=1,a,b;i<=m;i++) {
            scanf("%d%d",&a,&b);
            addedge(a,b,1);
            addedge(b,a,-1);
        }
    }
    
    void spfa(int u) {
        inque[u]=1;
        l=min(l,c[u]);
        r=max(r,c[u]);
        for(int i=g[u];~i;i=next[i]) if(!inque[v[i]]) {
            c[v[i]]=c[u]+dist[i];
            spfa(v[i]);
        }
    }
    
    void solve() {
        for(int i=1;i<=n;i++) if(!vis[i]) dfs(i,0,0);
        if(ans&&ans<=2) {
            printf("-1 -1
    ");
            return;    
        }
        if(ans) {
            maxres=ans;
            for(int i=3;i<=maxres;i++) if(maxres%i==0) {
                minres=i;
                break;
            }
        }
        else for(int i=1;i<=n;i++) if(!inque[i]) {
            l=r=c[i]=0;
            spfa(i);
            maxres+=r-l+1;
            minres=3;
        }
        if(maxres<3) maxres=minres=-1;
        printf("%d %d
    ",maxres,minres);
    }
    
    int main() {
        build();
        solve();
        return 0;
    }
  • 相关阅读:
    Python数据类型知识点
    CentOS上部署Kubernetes集群
    运维面试题(持续更新)
    shell拷贝文件到另一台机器
    第十一章——线程【01】
    07 类 | 类的静态成员
    【C++ Primer | 19】控制内存分配
    002 模板实参推断、重载与模板
    16 模板与泛型编程 | 定义模板
    C++ | 类
  • 原文地址:https://www.cnblogs.com/invoid/p/5609253.html
Copyright © 2011-2022 走看看