zoukankan      html  css  js  c++  java
  • POJ 1719 Shooting Contest

    /* 给定一个 r*c 的格子矩阵,有C发子弹,每列格子有2个白色的方块,在1,2,3,...c 列上开枪打白色的格子,打到一个,那么这个白色方块所在的行就算打到了,求怎样打,才能把所有的行全部打到,如果全部打到而且有多余的列,那么这列随便打一个方块就可以了,按列的1,2,3,4......C的顺序,输出要打的行号。很明显的一个二分匹配,普通的二分匹配算法就行了。*/

    #include <iostream>
    #include 
    <cstdio>
    #include 
    <algorithm>
    #include 
    <memory.h>
    using namespace std;

    #define INF 0x7ffffff
    #define MAXN 4000
    #define MAXE 20000

    struct Edge{
        
    int u,v;
        
    int next;
    }edge[MAXE];
    int net[MAXN],visit[MAXN],pre[MAXN];
    int nv,ne,index,r,c;
    void add_edge(const int& u, const int& v)
    {
        edge[index].next 
    = net[u];
        net[u] 
    = index;
        edge[index].v 
    = v;
        edge[index].u 
    = u;
        
    ++index;
    }
    int dfs(const int& u)
    {
        
    int i,v;
        
    for(i = net[u]; i != -1; i = edge[i].next)
        {
            v 
    = edge[i].v;
            
    if(!visit[v])
            {
                visit[v] 
    = 1;
                
    if(-1 == pre[v] || dfs(pre[v]))
                {
                    pre[v] 
    = u;
                    
    return 1;
                }
            }
        }
        
    return 0;
    }
    int main()
    {
        
    int i,j,k,h,tmp,sum,time,tmp1,tmp2,ans;
        scanf(
    "%d",&time);
        
    while(time--)
        {
            scanf(
    "%d%d",&r,&c);
            index 
    = ans = 0;
            memset(net,
    -1,sizeof(net));
            memset(pre,
    -1,sizeof(pre));
            
    for(i = 1;i <= c; ++i)
            {
                scanf(
    "%d%d",&tmp1,&tmp2);
                add_edge(tmp1,i);
                add_edge(tmp2,i);
                add_edge(i
    +r,tmp1);
            }
            
    if(c<r)
                ans 
    = -1;
            
    else
                
    for(i = 1;i <= r; ++i)
                {
                    memset(visit,
    0,sizeof(visit));
                    
    if(dfs(i))
                        
    ++ans;
                }
            
    if(ans < r)
                printf(
    "NO\n");
            
    else
            {
                
    for(i = 1;i <= c; ++i)
                {
                    
    if(i != 1) printf(" ");
                    
    if(pre[i] != -1)
                        printf(
    "%d",pre[i]);
                    
    else
                        printf(
    "%d",edge[net[i+r]].v);
                }
                printf(
    "\n");
            }
        }
        
    return 0;
    }

  • 相关阅读:
    [Java]用于将链表变成字符串并在元素之间插入分隔符的有用函数“String.join”
    Sql语法树示例 select username, ismale from userinfo where age > 20 and level > 5 and 1 = 1
    [Java]一段尚未雕琢的分词代码
    day44_Oracle学习笔记_03
    day43_Oracle学习笔记_02
    WinXP系统中的Oracle数据库如何以管理员身份登录
    Oracle 10G安装指导
    20个Linux服务器性能调优技巧
    Linux 上使用 Gmail SMTP 服务器发送邮件通知
    Netdata Linux下性能实时监测工具
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1662748.html
Copyright © 2011-2022 走看看