zoukankan      html  css  js  c++  java
  • 【NOI2008T1】假面舞会-DFS环处理+最大公因数

    测试地址:假面舞会

    做法:这题看上去就是找环然后求最大公因数,然后下一步就不会做了,看了题解就跪了......主要这个处理方法太神奇了。

    首先建图肯定不能按照原来的图建,因为需要枚举起点来走,会TLE,所以我们对于原图a->b这条边,连一条a->b边权为1,再连一条b->a边权为-1。如果图中有非零环,那么最大的答案就是所有非零环长的最大公因数,最小答案就是所有非零环长的最小的大于2的公因数。如果图中没有非零环,就统计每个连通块的最长链长,这个长度加上1就是这个连通块的最大答案,累加每个连通块的最大答案就是整体的最大答案,最小答案就是3。如果最大答案小于3则无解。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define inf 1000000000
    using namespace std;
    int n,m,cnt[100010],first[100010]={0},tot=0,maxn,minn;
    int len[100010]={0},ans1,ans2;
    struct edge {int v,d,next;} e[2000010];
    bool vis[100010]={0},flag=0;
    
    int gcd(int a,int b)
    {
      return b!=0?gcd(b,a%b):a;
    }
    
    void insert(int a,int b,int d)
    {
      e[++tot].v=b,e[tot].d=d,e[tot].next=first[a],first[a]=tot;
    }
    
    void dfs(int v)
    {
      vis[v]=1;
      maxn=max(maxn,cnt[v]);
      minn=min(minn,cnt[v]);
      for(int i=first[v];i;i=e[i].next)
      {
        if (!vis[e[i].v])
    	{
    	  cnt[e[i].v]=cnt[v]+e[i].d;
    	  dfs(e[i].v);
    	}
        else if (cnt[v]+e[i].d-cnt[e[i].v]!=0)
    	{
    	  flag=1;
    	  if (ans1==0) ans1=abs(cnt[v]+e[i].d-cnt[e[i].v]);
    	  else ans1=gcd(ans1,abs(cnt[v]+e[i].d-cnt[e[i].v]));
    	}
      }
    }
    
    int main()
    {
      scanf("%d%d",&n,&m);
      for(int i=1,a,b;i<=m;i++)
      {
        scanf("%d%d",&a,&b);
    	insert(a,b,1),insert(b,a,-1);
      }
      
      ans1=0;
      for(int i=1;i<=n;i++)
      if (!vis[i])
      {
        cnt[i]=0;
    	maxn=-inf,minn=inf;
    	dfs(i);
    	if (!flag) ans1+=maxn-minn+1;
      }
      
      ans1=abs(ans1);
      if (ans1<3) ans1=-1,ans2=-1;
      else if (!flag) ans2=3;
      else
      {
        for(int i=3;i<=ans1;i++)
    	  if (ans1%i==0) {ans2=i;break;}
      }
      
      printf("%d %d",ans1,ans2);
      
      return 0;
    }
    


  • 相关阅读:
    3D 服务器端以向量计算为主的角色位置的算法
    宇宙中可见物质为 4%,暗物质和暗能量占 96% 是怎么算出来的?
    量子纠缠
    “人的第一感觉(直觉)其实非常准”
    有哪些看似荒谬,其实很科学的理论@知乎、@量子力学
    CPU/寄存器/内存
    原子操作
    简单的介绍下WPF中的MVVM框架
    IOS开发中,TextField和TextView有何区别
    年后小结
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793753.html
Copyright © 2011-2022 走看看