HDU 3225 Flowers Placement 二分图第k优解

Description

Bytetown has a long tradition in organizing an international flower exhibition. Professor Feuerbach, a true flower lover, visited the exhibition this year. He was pleased by the most beautiful flowers and other plants around the world roses, orchids, magnolias, cactuses. All flowers were nicely placed. 

The flower placement that was the most appealing to him was composed of many kinds of flowers placed in a rectangular grid, such that each row of the grid contained each kind of flowers exactly once and each column of the grid contained each kind of flowers at most once. 

Professor Feuerbach is a good mathematician and soon he realized that the number of columns of the grid has to be the same as the number of different kinds of flowers in the placement. The different kinds of flowers are represented by numbers 1, 2..., N, where N is the number of different kinds of flowers. Soon he encountered a new problem. He would like to add one row of flowers to the placement without violating the rules stated above. (Note that he may not modify the existing rows and therefore he may not use any new kinds of flowers in the new rows.) It's quite easy, but he wants to know the K-th lexicographically valid placement.

Input

The input data set describes about 100 flower placements. In the first line the number of placements is given. 

Each flower placement description begins with three positive integers N (1≤N≤200), M (0≤M≤N), K (1≤K≤200) representing the number of columns and rows of the grid. The following M lines contain N integers each representing the kinds of flowers in one row of the placement.

Output

For each flower placement output one line containing N numbers, describing the added row. The numbers in the output file should be separated by exactly one space. If there are less than K valid placements, output -1 instead.

题意:

不太想说。

思路:

回溯遍历所有情况,注意剪枝。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#define maxn 300005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define N 205
bool vis[N];
vector<int> g[N];
int maps[N]; 
int ans[205];
int top,tot;
int n,m,k;
int use[205];
int save[205];
int find(int k,int st) 
{
    if(k<=st) return 0;
    for(int i=0;i<g[k].size();i++)
    {
        int boy=g[k][i];
        if(!vis[boy])
        {
            vis[boy]=1;
            if(maps[boy]==0||find(maps[boy],st))
            {
                maps[boy]=k;
                return 1;
            }
        }
    }
    return 0;
}
bool isok(int now,int flo)   
{
    if(maps[flo]==now) return true;
    int j;
    for(int i=1;i<=n;i++)
    {
        save[i]=maps[i];
        vis[i]=0;
        if(maps[i]==now) j=i; 
    }
    int t=maps[flo];
       
    maps[flo]=now;
    maps[j]=0;
    if(find(t,now)) return true;  
    else                           
    {

        for(int i=1;i<=n;i++)
            maps[i]=save[i];
    }
    return false;
}
bool dfs(int now)
{
    if(now==n+1)
    {
        if(++tot==k) return true;
        return false;
    }
    for(int i=0;i<g[now].size();i++)
    {
        int flo=g[now][i];
        if(!use[flo]&&isok(now,flo))
        {
            use[flo]=1;
            ans[now]=flo;
            if(dfs(now+1)) return true;
            use[flo]=0;
        }
    }
    return false;
}
int a[205][205];
int main()
{
    int cas;
    scanf("%d",&cas);
    int x;
    int ca=1;
    while(cas--)
    {
        for(int i=0;i<=n;i++) g[i].clear();
        memset(vis,0,sizeof(vis));
        memset(a,0,sizeof(a));

        memset(maps,0,sizeof(maps));
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&x);
                a[j][x]=1;
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(!a[i][j]) g[i].push_back(j);
            }
        }
        int Ans=0;
        for(int i=1;i<=n;i++)
        {
            memset(vis,0,sizeof(vis));
            Ans+=find(i,-1);
        }
        if(Ans!=n)
        {
            printf("Case #%d: -1\n",ca++);
            continue;
        }
        tot=0;
        memset(use,0,sizeof(use));
        if(dfs(1))
        {
            printf("Case #%d:",ca++);
            for(int i=1;i<=n;i++)
            {
                printf(" %d",ans[i]);
            }
        }
        else printf("Case #%d: -1",ca++);
        puts("");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值