zoukankan      html  css  js  c++  java
  • 匈牙利算法

    P1963 变换序列

    题目描述

    对于N个整数0,1,…,N-1,一个变换序列T可以将i变成Ti,其中:Ti∈{0,1,…,N-1}且 {Ti}={0,1,…,N-1}。 x,y∈{0,1,…,N-1},定义x和y之间的距离D(x,y)=min{|x-y|,N-|x-y|}。给定每个i和Ti之间的距离D(i,Ti),你需要求出一个满足要求的变换序列T。如果有多个满足条件的序列,输出其中字典序最小的一个。 说明:对于两个变换序列S和T,如果存在p<N,满足:对于i=0,1,…,p-1,Si=Ti且Sp<Tp,我们称S比T字典序小。
    N<=10000


    考试时乱水了20分,还不如暴力
    之后我一看
    发现每一个i最多有2个能与之匹配的T[i]
    明显的不带权二分图匹配
    可以用匈牙利算法
    但是

    如果至少存在一个满足要求的变换序列T,则输出一行为N个整数,表示你计算得到的字典序最小的T;
    ——题目

    在匈牙利算法匹配当中,如何才能保证字典序最小呢?
    其实就是从后往前寻找匹配,且优先匹配小的T(即连边时小的在前)。
    然后就可以兴奋的水过这一题了
    其实我考试时把正解写挂了
    代码蒯上

    #include<iostream>
    #include<iomanip>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int gotcha()
    {
        register char c = getchar();register long long x = 0, z = 1;
        for(;c>'9'||c<'0';c=getchar())z=c=='-'?-1:1;
        for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
        return x*z;
    }
    const int _ = 10002;
    int n,d[_],to[_]={0},ans[_],e[_][3]={0};
    bool ed[_]={0};
    int dis(int x,int y){return min(abs(x-y),n-abs(x-y));}
    bool finder(int now)
    {
        for(int i=1;i<=2;i++)
        {
            if(ed[e[now][i]])continue;
            ed[e[now][i]]=1;
            if(to[e[now][i]]==-1 || finder(to[e[now][i]]))
            {to[e[now][i]]=now;return 1;}
        }
        return 0;
    }
    int main()
    {
        register int i,j,k;
        n=gotcha();
        for(i=0;i<n;i++)d[i]=gotcha();
        for(i=0;i<n;i++)
        {
            j=(i+d[i])%n,k=(i-d[i]+n)%n;
            if(j>k)swap(j,k);
            e[i][1]=j;e[i][2]=k;
            to[i]=-1;
        }
        for(i=n-1;i>=0;i--)
        {
            memset(ed,0,sizeof(ed));
            if(!finder(i))
            {
                printf("%s","No Answer");
                return 0;
            }
        }
        for(i=0;i<n;i++)ans[to[i]]=i;
        for(i=0;i<n;i++)printf("%d ",ans[i]);
        return 0;
    }
    

    %%%Rank1 XZZ!

  • 相关阅读:
    软件开发的升级打怪攻略:从新手到高级工程师
    Java实现递归将嵌套Map里的字段名由驼峰转为下划线
    生活是什么
    批量下载网站图片的Python实用小工具
    工作的方法
    工作的心境
    LODOP直接导出图片不弹框
    LODOP打印table超宽用省略号带'-'的内容换行问题
    LODOP打印table表格宽度固定-超宽隐藏
    如何领购和作废电子发票流程
  • 原文地址:https://www.cnblogs.com/finder-iot/p/7610581.html
Copyright © 2011-2022 走看看