• BZOJ 1562 变换序列 二分图匹配+字典序


    题目链接:

     https://www.lydsy.com/JudgeOnline/problem.php?id=1562

    题目大意:

    思路:

    逆序匹配,加边匹配的时候保持字典序小的先加入。

    具体证明:https://www.byvoid.com/zhs/blog/noi-2009-transform

      1 #include<bits/stdc++.h>
      2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
      3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
      4 #define Min(a, b) ((a) < (b) ? (a) : (b))
      5 #define Mem(a) memset(a, 0, sizeof(a))
      6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
      7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
      8 #define lson ((o)<<1)
      9 #define rson ((o)<<1|1)
     10 #define Accepted 0
     11 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
     12 using namespace std;
     13 inline int read()
     14 {
     15     int x=0,f=1;char ch=getchar();
     16     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 
     21 typedef long long ll;
     22 const int maxn = 10000 + 10;
     23 const int MOD = 1000000007;//const引用更快,宏定义也更快
     24 const int INF = 1e9 + 7;
     25 const double eps = 1e-6;
     26 
     27 int n, m;
     28 vector<int>Map[maxn];
     29 int cx[maxn], cy[maxn];
     30 bool vis[maxn];
     31 //cx[i]表示X部i点匹配的Y部顶点的编号
     32 //cy[i]表示Y部i点匹配的X部顶点的编号
     33 
     34 bool dfs(int u)//dfs进入的都是X部的点
     35 {
     36     for(int i = 0; i < Map[u].size(); i++)//枚举Y部的点,判断X部的u和Y部的v是否存在路径
     37     {
     38         int v = Map[u][i];
     39         //如果存在路径并且还没被标记加入增广路
     40         if(!vis[v])//vis数组只标记Y组
     41         {
     42             vis[v] = 1;//标记加入增广路
     43 
     44             //如果Y部的点v还未被匹配
     45             //或者已经被匹配了,但是可以从v点原来匹配的cy[v]找到一条增广路
     46             //说明这条路就可是一个正确的匹配
     47             if(cy[v] == -1 || dfs(cy[v]))
     48             {
     49                 cx[u] = v;//可以匹配,进行匹配
     50                 cy[v] = u;
     51                 return 1;
     52             }
     53         }
     54     }
     55     return 0;//不能匹配
     56 }
     57 int maxmatch()//匈牙利算法主函数
     58 {
     59     int ans = 0;
     60     memset(cx, -1, sizeof(cx));
     61     memset(cy, -1, sizeof(cy));
     62     for(int i = n - 1; i >= 0; i--)//逆序匹配 保证最优解
     63     {
     64         if(cx[i] == -1)//如果X部的i还未匹配
     65         {
     66             memset(vis, 0, sizeof(vis));//每次找增广路的时候清空vis
     67             ans += dfs(i);
     68         }
     69     }
     70     return ans;
     71 }
     72 int main()
     73 {
     74     IOS;
     75     cin >> n;
     76     int x, ti;
     77     for(int i = 0; i < n; i++)
     78     {
     79         cin >> x;
     80         //abs(i - ti) = x  => ti = i - x or i + x
     81         //abs(i - ti) = n - x; => ti = i - (n - x) or i + n - x
     82         //等价于ti = (i - x + n) % n or (i + x) % n;
     83         int u = (i - x + n) % n;
     84         int v = (i + x) % n;
     85         if(u > v)swap(u, v);//保证字典序小的在前面
     86         Map[i].push_back(u);
     87         Map[i].push_back(v);
     88     }/*
     89     for(int i = 0; i < n; i++)
     90     {
     91         cout<<i<<" : ";
     92         for(int j = 0; j < Map[i].size(); j++)cout<<Map[i][j]<<" ";
     93         cout<<endl;
     94     }*/
     95     if(maxmatch() != n)cout<<"No Answer
    ";
     96     else
     97     {
     98         cout<<cx[0];
     99         for(int i = 1; i < n; i++)cout<<" "<<cx[i];
    100         cout<<"
    ";
    101     }
    102     return Accepted;
    103 }
  • 相关阅读:
    PyQT_Group
    单例模式演示-1-39-07
    RSqlBuilder
    RExcel
    RJson
    NodeJs开发目录
    NodeJs事件驱动
    NodeJs实用工具util
    NodeJs之global,process
    NodeJs两个简单调试技巧
  • 原文地址:https://www.cnblogs.com/fzl194/p/9678404.html
Copyright © 2020-2023  润新知