• BZOJ 1562 [NOI2009]变换序列:二分图匹配


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1562

    题意:

      给定n,定义D(x,y) =  min(|x-y|, n-|x-y|),然后给定数组d[i] = D(i,T[i])。

      让你求一个0到n-1的排列T,下标i∈[0,n-1],满足给定的D(i,T[i]),且字典序最小。

      若没有答案输出"No Answer"。

    题解:

      其实就是让你求一个排列T,其中T[i]要么填(i+d[i])%n,要么填(i-d[i]+n)%n。

      所以对于每个i,向它能填的两个数连边,跑一边最大匹配即可。

      又因为要求字典序最小,所以对于每个i连边时,应先连向较小的那个数。然后跑匈牙利的时候按从n-1到0的顺序跑即可。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <vector>
     5 #define MAX_N 10005
     6 
     7 using namespace std;
     8 
     9 int n;
    10 int d[MAX_N];
    11 int vis[MAX_N];
    12 int mat[MAX_N];
    13 int rmat[MAX_N];
    14 int edge[MAX_N][2];
    15 
    16 bool hungary(int now,int cnt)
    17 {
    18     for(int i=0;i<2;i++)
    19     {
    20         int temp=edge[now][i];
    21         if(vis[temp]!=cnt)
    22         {
    23             vis[temp]=cnt;
    24             if(mat[temp]==-1 || hungary(mat[temp],cnt))
    25             {
    26                 mat[temp]=now;
    27                 rmat[now]=temp;
    28                 return true;
    29             }
    30         }
    31     }
    32     return false;
    33 }
    34 
    35 int main()
    36 {
    37     cin>>n;
    38     for(int i=0;i<n;i++)
    39     {
    40         cin>>d[i];
    41         if(d[i]>n/2)
    42         {
    43             cout<<"No Answer"<<endl;
    44             return 0;
    45         }
    46         int x=(i+d[i])%n;
    47         int y=(i-d[i]+n)%n;
    48         edge[i][0]=min(x,y);
    49         edge[i][1]=max(x,y);
    50     }
    51     memset(vis,0,sizeof(vis));
    52     memset(mat,-1,sizeof(mat));
    53     for(int i=n-1;i>=0;i--)
    54     {
    55         if(!hungary(i,i+1))
    56         {
    57             cout<<"No Answer"<<endl;
    58             return 0;
    59         }
    60     }
    61     for(int i=0;i<n;i++) cout<<rmat[i]<<" ";
    62     cout<<endl;
    63 }
  • 相关阅读:
    水题大战Vol.3 B. DP搬运工2
    火题小战 C. 情侣?给我烧了!
    火题小战 B. barbeque
    火题小战 A.玩个球
    P6087 [JSOI2015]送礼物 01分数规划+单调队列+ST表
    NOI2020D1T1美食家
    Java 的随机数
    MySQL 配置文件的配置
    NOIP2020准(ge)备(zi)日记
    android开发EditText禁止输入中文密码的解决方法
  • 原文地址:https://www.cnblogs.com/Leohh/p/8439186.html
Copyright © 2020-2023  润新知