首页 > 其他 > 详细

bzoj1562: [NOI2009]变换序列

时间:2016-05-15 10:49:04      阅读:120      评论:0      收藏:0      [点我收藏+]

匈牙利匹配。

在邻接表中每条边以终点升序排序。从x最后一个点往前进行增广,这样每个点首先都能匹配到字典序最小的位置,如果前面的点找不到匹配点时,后面的点就匹配到稍大一点的y匹配点上。

建图说明:每个点有且只会有俩个点符合距离的要求,可以想想为什么。

y点要+n与x点区分开来。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 30000 + 10;

vector<int> g[maxn];
bool vis[maxn];
int p[maxn];
int n;

bool find(int u) {
    if(vis[u]) return false;
    vis[u]=true;
    
    for(int i=0,v;i<g[u].size();i++) {
        v=g[u][i];
        if(!p[v] || find(p[v])) {
            p[v]=u;
            p[u]=v;
            return true;
        }
    }
    return false;
}


int main() {
    scanf("%d",&n);
    for(int i=0,d;i<n;i++){ 
        scanf("%d",&d);
        int a=(i+d)%n,b=(i+n-d)%n;
        if(a>b) swap(a,b);
        g[i].push_back(a+n);
        g[i].push_back(b+n);    
    }
    for(int i=n-1;i>=0;i--) {
        memset(vis,0,sizeof(vis));
        if(!find(i)) {
            printf("No Answer");
            return 0;    
        }
    }
    for(int i=0;i<n;i++) if(i) printf(" %d",p[i]-n);
    else printf("%d",p[i]-n);
    return 0;
}

bzoj1562: [NOI2009]变换序列

原文:http://www.cnblogs.com/invoid/p/5494639.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!