zoukankan      html  css  js  c++  java
  • USACO 1.3 warmhole

    一道黄题刚了三天,把数据答案记错也是没谁了

    从这道题还是看出我很多不足的,果然做黄题还是有意义

    地址:https://www.luogu.org/problemnew/show/P1444

    一开始我想直接建图找环,后来发现这是不行的,这是一个既有有向边又有无向边的图,直接找环很麻烦

    稍加分析后发现,从一个点,如果上一次我是从虫洞走来的,这次我只能步行;如果我是步行来的,这次我必然走虫洞

    因此,要把虫洞和步行分开存,对于每两个点i,j如果其y坐标相等则连一条有向边,然后枚举虫洞的匹配情况,最后在枚举完成后进行判环,如下:

    令to[i]为步行到的点,con[i]为i的虫洞,则位于i,要先走到to[i],再走向to[i]的虫洞,即i = con[to[i]],记录instack判环即可

    但是还有一个问题:如果有多个点的y都相同,这时是不能盲目连边的

    因此,将点按y坐标排序,y相同时按x排序,对于一个点i,如果i和i +1的y相同,则在i和i + 1间连,这样能保证不会出现例如最小和第三小的点间连边的情况(而这本来是不可能的)

    以上,就做出了这道题

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
      ll ans = 0,op = 1;
      char ch = getchar();
      while(ch < '0' || ch > '9')
        {
          if(ch == '-') op = -1;
          ch = getchar();
        }
      while(ch >= '0' && ch <= '9')
        {
          (ans *= 10) += ch - '0';
          ch = getchar();
        }
      return ans * op;
    }
    int n;
    struct node
    {
      ll x,y;
    }a[20];
    bool cmp(const node &a,const node &b)
    {
      return a.y < b.y || (a.y == b.y && a.x < b.x);
    }
    int con[101],to[101];
    int ans = 0;
    bool vis[1001];
    bool instack[1001];
    bool flag = 0;
    bool dfs_cy(int u)
    {
      while(to[u])
        {
          if(instack[u]) return 1;
          instack[u] = 1;
          u = con[to[u]];
        }
      return 0;
    }
    void dfs(int k)
    {
      if(k > n)
        {
          flag = 0;
          for(int i = 1;i <= n && !flag;i++) memset(instack,0,sizeof(instack)),flag |= dfs_cy(i);
          ans += flag;
        }
      if(con[k]) dfs(k + 1);
      else
        {
      for(int i = k + 1;i <= n;i++)
        {
        if(!con[i])
          {
        con[i] = k,con[k] = i;
        dfs(k + 1);
        con[i] = con[k] = 0;
          }
        }
        }
    }
    bool ok[101][101];
    int main()
    {
      n = read();
      for(int i = 1;i <= n;i++) a[i].x = read(),a[i].y = read();
      sort(a + 1,a + 1 + n,cmp);
      for(int i = 1;i <= n;i++) if(a[i].y == a[i + 1].y) to[i] = i + 1;
      //for(int i = 1;i <= n;i++) printf("%d ",to[i]);
      //cout << endl;
      dfs(1);
      printf("%d",ans);
    }
  • 相关阅读:
    思维导图 第八章 项目质量管理
    思维导图 第七章 项目成本管理
    redis安装与配置
    思维导图 第六章 项目进度管理
    思维导图 第五章 项目范围管理
    Linux下用户-组权限配置
    意灵魔法馆首页的初步设计
    try catch自定义异常类的使用
    使用freemarker时,生成的html出现乱码
    乱码问题
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/9972915.html
Copyright © 2011-2022 走看看