zoukankan      html  css  js  c++  java
  • codechef January Challenge 2014 Sereja and Graph

    题目链接:http://www.codechef.com/JAN14/problems/SEAGRP

    【题意】

         给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1.

    【分析】

         从结论入手,每个点的度恰好为1,那么就意味着每个点只能连接一个点,这样问题就转化为图中的点能否刚好两两配对

        对于奇数个点肯定是不行的,因为一定存在一个点不存在与之配对的点。
        如果点是偶数,那么就要求这个图的最大匹配,看匹配树是否为点数的一半。

        求匹配的方法和二分图类似,不断找增广路更新匹配数就好了。

    【代码】

          第一次手写增广路代码~写的时候忘记判断增广路是否重点了于是WA了,还好后来想到了。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <cmath>
     4 #include <iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 int n,m;
     8 int map[102][102];
     9 int match[102][102];
    10 int du[102];
    11 int path[102];
    12 bool ifv[102];
    13 int be;
    14 bool dfs(int i,int k)
    15 {
    16     if ((k&1) && !du[i] )
    17     {
    18         int t=k-1;
    19         while (t>=0)
    20         {
    21             if (match[i][path[t]]==0) {++du[i];++du[path[t]];}
    22              else {--du[i];--du[path[t]];}
    23             match[i][path[t]]=!match[i][path[t]];
    24             match[path[t]][i]=!match[path[t]][i];
    25             i=path[t];
    26             --t;
    27         }
    28         return true;
    29     }
    30     for (int j=1;j<=n;++j)
    31     {
    32         if (map[i][j]==-1) continue;
    33         if (match[i][j]!=(k&1) ) continue;
    34         if (ifv[j]) continue;
    35         path[k]=i;
    36         ifv[j]=true;
    37         if (dfs(j,k+1)) return true;
    38     }
    39     return false;
    40 }
    41 int main()
    42 {
    43     int T;
    44     scanf("%d",&T);
    45     while (T--)
    46     {
    47        memset(map,-1,sizeof map);
    48        memset(match,0,sizeof match);
    49        memset(du,0,sizeof du);
    50        scanf("%d%d",&n,&m);
    51        for (int i=0;i<m;++i)
    52        {
    53            int a,b;
    54            scanf("%d%d",&a,&b);
    55            map[a][b]=map[b][a]=1;
    56        }
    57        if (n&1) puts("NO");
    58        else
    59        {
    60              int ans=0;
    61              for (int i=1;i<=n;++i)
    62              {
    63                  memset(ifv,0,sizeof ifv);
    64                  ifv[i]=true;
    65                  if (!du[i] && dfs(i,0)) ++ans;
    66              }
    67             if (ans==n/2) puts("YES"); else puts("NO");
    68        }
    69     }
    70 }
    View Code
  • 相关阅读:
    mysql索引类型 normal, unique, full text
    16.信号量互斥编程
    15.信号通信编程
    14.有名管道通信
    13.无名管道通讯编程
    12.多进程程序的操作
    11.进程控制理论
    10.时间编程
    9. 库函数方式文件编程
    8.Linux文件编程
  • 原文地址:https://www.cnblogs.com/wuminye/p/3504565.html
Copyright © 2011-2022 走看看