zoukankan      html  css  js  c++  java
  • poj 1719

    Shooting Contest

    题意:r行c列的矩阵上,每列有两个白色点,用c发子弹打到矩阵上的点,能否使每列有且只有一个白点被击中而每行起码有一个白点被击中(这个题意当初没理解好,纠结一个下午都不知道为什么WA)?若能,则求其中一个白点组合;不能则输出“NO”。

    分析:受人指教,这个图可以把行作为一个集合,列作为一个集合,若第i行第j列是白色的,则有边(i,j),可以保证这样的图是二分图。只要在这个图里求出最大匹配(在匹配的情况下,每列都只会选到一行),匹配数等于r则能满足条件(有匹配的列都直接输出匹配点,注意c可能大于r,因此没匹配到的列里每列随便拿出一个白点就能得出解)。

    View Code
     1 #include<cstdio>
     2 #include<vector>
     3 using namespace std;
     4 vector<int> vex[5000];
     5 int r,c,max_match,mat[5000];
     6 bool visited[5000];
     7 int path(int u)
     8 {
     9     int i,v;
    10     for(i=0;i<vex[u].size();i++)
    11     {
    12         v=vex[u][i];
    13         if(!visited[v])
    14         {
    15             visited[v]=true;
    16             if(mat[v]==-1 || path(mat[v]))
    17             {
    18                 mat[v]=u;
    19                 mat[u]=v;
    20                 return 1;
    21             }
    22         }
    23     }
    24     return 0;
    25 }
    26 int Hungary()
    27 {
    28     int ans=0,i,j;
    29     for(i=1;i<=c+r;i++)
    30         mat[i]=-1;
    31     for(i=1;i<=c;i++)
    32     {
    33         for(j=1;j<=c+r;j++)
    34             visited[j]=false;
    35         ans+=path(i);
    36     }
    37     return ans;
    38 }
    39 int main()
    40 {
    41     int t,i,a,b;
    42     scanf("%d",&t);
    43     while(t--)
    44     {
    45         scanf("%d%d",&r,&c);
    46         for(i=1;i<=c;i++)
    47         {
    48             scanf("%d%d",&a,&b);
    49             vex[i].push_back(a+c);
    50             vex[i].push_back(b+c);
    51             vex[a+c].push_back(i);
    52             vex[b+c].push_back(i);
    53         }
    54         max_match=Hungary();
    55         if(max_match==r)
    56         {
    57             printf("%d",mat[1]-c);
    58             for(i=2;i<=c;i++)
    59             {
    60                 if(mat[i]!=-1)
    61                     printf(" %d",mat[i]-c);
    62                 else
    63                     printf(" %d",vex[i][1]-c);
    64             }
    65             printf("\n");
    66         }
    67         else
    68             printf("NO\n");
    69         for(i=1;i<=c+r;i++)
    70             vex[i].clear();
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    Jmeter在命令行运行技巧
    Tomcat6 一些调优设置内存和连接数
    用例结构优化心得
    LoadRunner 调用dll方法
    DLL接口自动化测试总结
    Loadrunner进行md5加密方法
    Loadrunner检查点使用总结
    网络上可供测试的Web Service
    04 json,xml混合封装通信
    03 xml封装通信接口
  • 原文地址:https://www.cnblogs.com/ZShogg/p/2950410.html
Copyright © 2011-2022 走看看