图论:TZOJ二分图练习

Posted llhsbg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论:TZOJ二分图练习相关的知识,希望对你有一定的参考价值。

目录 

1023  1037  1321  2021  2380

2733  3635  5839  5840  5842

1023: Taxi Cab Scheme 返回顶部

描述

Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coordination of the cabs in order to pick up the customers calling to get a cab as soon as possible,there is also a need to schedule all the taxi rides which have been booked in advance.Given a list of all booked taxi rides for the next day, you want to minimise the number of cabs needed to carry out all of the rides.
For the sake of simplicity, we model a city as a rectangular grid. An address in the city is denoted by two integers: the street and avenue number. The time needed to get from the address a, b to c, d by taxi is |a - c| + |b - d| minutes. A cab may carry out a booked ride if it is its first ride of the day, or if it can get to the source address of the new ride from its latest,at least one minute before the new ride‘s scheduled departure. Note that some rides may end after midnight.

输入

On the first line of the input is a single positive integer N, telling the number of test scenarios to follow. Each scenario begins with a line containing an integer M, 0 < M < 500, being the number of booked taxi rides. The following M lines contain the rides. Each ride is described by a departure time on the format hh:mm (ranging from 00:00 to 23:59), two integers a b that are the coordinates of the source address and two integers c d that are the coordinates of the destination address. All coordinates are at least 0 and strictly smaller than 200. The booked rides in each scenario are sorted in order of increasing departure time.

输出

For each scenario, output one line containing the minimum number of cabs required to carry out all the booked taxi rides.

样例输入

2
2
08:00 10 11 9 16
08:07 9 16 10 11
2
08:00 10 11 9 16
08:06 9 16 10 11

样例输出

1
2

题意

每天多项出租车程,给定乘车时间,起点位置,终点位置。两点之间的行车时间为横坐标差的绝对值和纵坐标差的绝对值之和。

出租车要求提前至少1分钟到达目的地接送乘客。

思路:求出每项车程到达目的地的时间,枚举每项车程,对于能从终点在规定时间内到达另一项车程起点的,建边。

求最大独立集

技术图片
#include<bits/stdc++.h>
using namespace std;
int a[505][505],match[505],vis[505],n;
int e[505][4],times[505];
bool dfs(int x){
      for(int i=1;i<=n;i++){
          if(!vis[i]&&a[x][i]){
            vis[i]=1;
            if(match[i]<0||dfs(match[i])){
                match[i]=x;
              return true;
            }
          }
      }
      return false;
}
int find(){
      int ans=0;
      memset(match,-1,sizeof(match));
      for(int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));
        if(dfs(i))ans++;
      }
      return ans;
}
int main(){
     int t;
     scanf("%d",&t);
     while(t--)
     {
     memset(a,0,sizeof(a));
     scanf("%d",&n);
     int h,m;
     for(int i=1;i<=n;i++)scanf("%d:%d%d%d%d%d",&h,&m,&e[i][0],&e[i][1],&e[i][2],&e[i][3]),times[i]=h*60+m;
     for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(times[i]+abs(e[i][0]-e[i][2])+abs(e[i][1]-e[i][3])+abs(e[i][2]-e[j][0])+abs(e[i][3]-e[j][1])<times[j]){
                a[i][j]=1;
            }
        }
     }
     printf("%d
",n-find());
     }
}
View Code

1037: Guardian of Decency 返回顶部

描述

Frank N. Stein is a very conservative high-school teacher. He wants to take some of his students on an excursion, but he is afraid that some of them might become couples. While you can never exclude this possibility, he has made some rules that he thinks indicates a low probability two persons will become a couple:

  • Their height differs by more than 40 cm.
  • They are of the same sex.
  • Their preferred music style is different.
  • Their favourite sport is the same (they are likely to be fans of different teams and that would result in fighting).
So, for any two persons that he brings on the excursion, they must satisfy at least one of the requirements above. Help him find the maximum number of persons he can take, given their vital information

输入

The first line of the input consists of an integer T ≤ 100 giving the number of test cases. The first line of each test case consists of an integer N ≤ 500 giving the number of pupils. Next there will be one line for each pupil consisting of four space-separated data items:

  • an integer h giving the height in cm;
  • a character ‘F‘ for female or ‘M‘ for male;
  • a string describing the preferred music style;
  • a string with the name of the favourite sport.
No string in the input will contain more than 100 characters, nor will any string contain any whitespace.

输出

For each test case in the input there should be one line with an integer giving the maximum number of eligible pupils.

样例输入

2
4
35 M classicism programming
0 M baroque skiing
43 M baroque chess
30 F baroque soccer
8
27 M romance programming
194 F baroque programming
67 M baroque ping-pong
51 M classicism programming
80 M classicism Paintball
35 M baroque ping-pong
39 F romance ping-pong
110 M romance Paintball

样例输出

3
7

题意:为了阻止情侣的产生,我们尽量选择不带可能成为情侣的两人出游,当同时满足 身高差小于40cm,性别不同,喜欢的音乐风格相同,喜欢的体育项目不同,两个

人就能成为情侣,求最多能带多少人出游

思路:

求最大独立集,当二分图按男女分组时,最大独立集为 人数 - 最大匹配数。

未分时 最大独立集为 人数-最大匹配数/2

技术图片
#include<bits/stdc++.h>
using namespace std;
int a[505][505],match[505],vis[505],n;
int height[505];
string sex[505],music[505],sport[505];
bool dfs(int x){
      for(int i=1;i<=n;i++){
          if(!vis[i]&&a[x][i]){
            vis[i]=1;
            if(match[i]<0||dfs(match[i])){
                match[i]=x;
              return true;
            }
          }
      }
      return false;
}
int find(){
      int ans=0;
      memset(match,-1,sizeof(match));
      for(int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));
        if(dfs(i))ans++;
      }
      return ans;
}
int main(){
     int t;
     cin>>t;
     while(t--)
     {
     memset(a,0,sizeof(a));
     cin>>n;
     for(int i=1;i<=n;i++)cin>>height[i]>>sex[i]>>music[i]>>sport[i];
     for(int i=1;i<=n;i++){
        for(int j=0;j<=n;j++){
            if(abs(height[j]-height[i])<=40)
            if(sex[i]!=sex[j])
            if(music[i]==music[j])
            if(sport[i]!=sport[j])a[i][j]=1;
        }
     }
     printf("%d
",n-find()/2);
     }
}
View Code

1321: Girls and Boys 返回顶部

描述

the second year of the university somebody started a study on the romantic relations between the students. The relation “romantically involved” is defined between one girl and one boy. For the study reasons it is necessary to find out the maximum set satisfying the condition: there are no two students in the set who have been “romantically involved”. The result of the program is the number of students in such a set.

输入

The input contains several data sets in text format. Each data set represents one set of subjects of the study, with the following description:

the number of students
the description of each student, in the following format
student_identifier:(number_of_romantic_relations) student_identifier1 student_identifier2 student_identifier3 ...
or
student_identifier:(0)

The student_identifier is an integer number between 0 and n-1, for n students.

输出

For each given data set, the program should write to standard output a line containing the result.

样例输入

7
0: (3) 4 5 6
1: (2) 4 6
2: (0)
3: (0)
4: (2) 0 1
5: (1) 0
6: (2) 0 1
3
0: (2) 1 2
1: (1) 0
2: (1) 0

样例输出

5
2

题意

有多对可能的情侣,求最多有多少只单身狗

思路

求最大独立集,因为没有分男女,最大匹配数求得后应当除2

技术图片
#include<bits/stdc++.h>
using namespace std;
int match[505],vis[505],n,m,t;
vector<int> v[505];
bool dfs(int x){
      for(int i=0;i<v[x].size();i++){
          int u=v[x][i];
          if(!vis[u]){
            vis[u]=1;
            if(match[u]==-1||dfs(match[u])){
                match[u]=x;
               return true;
            }
          }
      }
      return false;
}
int main(){
     while(~scanf("%d",&t)){
          for(int i=0;i<t;i++)v[i].clear();
          for(int i=1;i<=t;i++){
            int x,y,z;
            scanf("%d: (%d)",&x,&y);
            for(int j=1;j<=y;j++){
                scanf("%d",&z);
                v[x].push_back(z);
            }
          }
          int ans=0;
          memset(match,-1,sizeof(match));
          for(int i=0;i<t;i++){
            memset(vis,0,sizeof(vis));
            if(dfs(i))ans++;
          }
          printf("%d
",t-ans/2);
     }
}
View Code

2021: Cat vs. Dog 返回顶部

描述

The latest reality show has hit the TV: ``Cat vs. Dog‘‘. In this show, a bunch of cats and dogs compete for the very prestigious Best Pet Ever title. In each episode, the cats and dogs get to show themselves off, after which the viewers vote on which pets should stay and which should be forced to leave the show.

Each viewer gets to cast a vote on two things: one pet which should be kept on the show, and one pet which should be thrown out. Also, based on the universal fact that everyone is either a cat lover (i.e. a dog hater) or a dog lover (i.e. a cat hater), it has been decided that each vote must name exactly one cat and exactly one dog.

Ingenious as they are, the producers have decided to use an advancement procedure which guarantees that as many viewers as possible will continue watching the show: the pets that get to stay will be chosen so as to maximize the number of viewers who get both their opinions satisfied. Write a program to calculate this maximum number of viewers.

输入

On the first line one positive number: the number of testcases, at most 100. After that per testcase:

One line with three integers cdv (1 ≤ cd ≤ 100 and 0 ≤ v ≤ 500): the number of cats, dogs, and voters.v lines with two pet identifiers each. The first is the pet that this voter wants to keep, the second is the pet that this voter wants to throw out. A pet identifier starts with one of the characters `C‘ or `D‘, indicating whether the pet is a cat or dog, respectively. The remaining part of the identifier is an integer giving the number of the pet (between 1 and c for cats, and between 1 and d for dogs). So for instance, ``D42‘‘ indicates dog number 42.

输出

Per testcase:

One line with the maximum possible number of satisfied voters for the show.

样例输入 

2
1 1 2
C1 D1
D1 C1
1 2 4
C1 D1
C1 D1
C1 D2
D2 C1

样例输出

1
3

题意

有v个观众,每个人投给自己喜欢的猫(或者狗)和讨厌的狗(或者猫),如果出现喜欢的和别人讨厌的相同,则其中一人会不满意。 
现要求得是最大满意的观众是多少。 

思路:根据喜欢猫讨厌狗 和喜欢狗讨厌猫,可以将观众分为两类,在两类中分布枚举 观众 i 和观众 j 如果两者之间的出现一人的喜欢与另一人的讨厌相同

则建边。最后求二分图最大独立集

技术图片
#include<bits/stdc++.h>
using namespace std;
struct node
{
    string x,y;
}c[505],d[505];
int a[505][505],match[505],vis[505],dp,cp;
int find(int x)
{
    for(int i=1;i<=dp;i++)
    {
        if(!vis[i]&&a[x][i])
        {
            vis[i]=1;
            if(match[i]==-1||find(match[i]))
            {
                match[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m,k;
        cp=0,dp=0;
        cin>>n>>m>>k;
        for(int i=1;i<=k;i++)
        {
            string s,s1;
            cin>>s>>s1;
            if(s[0]==C)c[++cp].x=s,c[cp].y=s1;
            else d[++dp].x=s,d[dp].y=s1;
        }
        memset(a,0,sizeof(a));
        for(int i=1;i<=cp;i++)
        {
            for(int j=1;j<=dp;j++)
            {
                if(c[i].x==d[j].y||c[i].y==d[j].x)a[i][j]=1;
            }
        }
        memset(match,-1,sizeof(match));
        int ans=0;
        for(int i=1;i<=cp;i++)
        {
            memset(vis,0,sizeof(vis));
            if(find(i))ans++;
        }
        printf("%d
",k-ans);
    }
}
View Code

2380: Gopher II 返回顶部

描述

The gopher family, having averted the canine threat, must face a new predator.

The are n gophers and m gopher holes, each at distinct (x, y) coordinates. A hawk arrives and if a gopher does not reach a hole in s seconds it is vulnerable to being eaten. A hole can save at most one gopher. All the gophers run at the same velocity v. The gopher family needs an escape strategy that minimizes the number of vulnerable gophers.

输入

The input contains several cases. The first line of each case contains four positive integers less than 100: n, m, s, and v. The next n lines give the coordinates of the gophers; the following m lines give the coordinates of the gopher holes. All distances are in metres; all times are in seconds; all velocities are in metres per second.

输出

Output consists of a single line for each case, giving the number of vulnerable gophers.

样例输入

2 2 5 10
1.0 1.0
2.0 2.0
100.0 100.0
20.0 20.0

样例输出

1

题意:

有n个地鼠和m个地鼠洞,每个地鼠和洞都有一个(x , y)坐标,已知地鼠速度均为v,现有t秒时间让地鼠进洞。否则会被老鹰吃掉,一个洞只能容纳一只地鼠。求最少有多少地鼠会被吃掉

思路:地鼠数-最大匹配数

技术图片
#include<bits/stdc++.h>
using namespace std;
int a[105][105],match[105],vis[105],n,m,s,v;
double x[105],y[105],xx[105],yy[105];
bool dfs(int x){
      for(int i=1;i<=m;i++){
          if(!vis[i]&&a[x][i]){
            vis[i]=1;
            if(match[i]<0||dfs(match[i])){
                match[i]=x;
              return true;
            }
          }
      }
      return false;
}
int find(){
      int ans=0;
      memset(match,-1,sizeof(match));
      for(int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));
        if(dfs(i))ans++;
      }
      return ans;
}
int dis(int u,int z){
    return sqrt((x[u]-xx[z])*(x[u]-xx[z])+(y[u]-yy[z])*(y[u]-yy[z]));
}
int main(){
     while(~scanf("%d%d%d%d",&n,&m,&s,&v))
     {
     memset(a,0,sizeof(a));
     for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);
     for(int i=1;i<=m;i++)scanf("%lf%lf",&xx[i],&yy[i]);
     for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(dis(i,j)<s*v){
                a[i][j]=1;
            }
        }
     }
     printf("%d
",n-find());
     }
}
View Code

2733: 棋盘游戏 返回顶部

描述

小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,这当然很简单,但是Gardon限制了只有某些格子才可以放,小希还是很轻松的解决了这个问题(见下图)注意不能放车的地方不影响车的互相攻击。
所以现在Gardon想让小希来解决一个更难的问题,在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。Gardon想让小希算出有多少个这样的重要点,你能解决这个问题么?

技术图片

 

输入

输入包含多组数据,
第一行有三个数N、M、K(1<N,M<=100 1<K<=N*M),表示了棋盘的高、宽,以及可以放“车”的格子数目。接下来的K行描述了所有格子的信息:每行两个数X和Y,表示了这个格子在棋盘中的位置。

输出

对输入的每组数据,按照如下格式输出:
Board T have C important blanks for L chessmen.

样例输入

3 3 4
1 2
1 3
2 1
2 2
3 3 4
1 2
1 3
2 1
3 2

样例输出

Board 1 have 0 important blanks for 2 chessmen.
Board 2 have 3 important blanks for 3 chessmen.

思路

先建图求出二分图最大匹配数,在根据已知的匹配情况,将行列匹配的点依次禁用,重新进行二分图匹配,若求得答案与最大匹配数不相等,则关键点+1、

技术图片
#include<bits/stdc++.h>
using namespace std;
int a[105][105],match[105],vis[105],n,m,t,cas,p[105];
bool dfs(int x){
      for(int i=1;i<=m;i++){
          if(!vis[i]&&a[x][i]){
            vis[i]=1;
            if(match[i]<0||dfs(match[i])){
                match[i]=x;
              return true;
            }
          }
      }
      return false;
}
int find(){
      int ans=0;
      memset(match,-1,sizeof(match));
      for(int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));
        if(dfs(i))ans++;
      }
      return ans;
}
int main(){
     cas=0;
     while(~scanf("%d%d%d",&n,&m,&t)){
           memset(a,0,sizeof(a));
           while(t--){
               int x,y;
               scanf("%d%d",&x,&y);
               a[x][y]=1;
           }
           int k=find();
           for(int i=1;i<=m;i++)p[i]=match[i];
           int ans=0;
           for(int i=1;i<=m;i++){
              if(p[i]!=-1){
                a[p[i]][i]=0;
                if(find()<k)ans++;
                a[p[i]][i]=1;
              }
           }
           printf("Board %d have %d important blanks for %d chessmen.
",++cas,ans,k);
     }
}
View Code

3635: 过山车 返回顶部

描述 

RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。聪明的Acmer,你可以帮忙算算最多有多少对组合可以坐上过山车吗?

输入

输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。

输出

对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。

样例输入

6 3 3
1 1
1 2
1 3
2 1
2 3
3 1
0

样例输出

3

思路:

建图求二分图最大匹配数

技术图片
#include<bits/stdc++.h>
using namespace std;
int match[505],vis[505],n,m,t;
vector<int> v[505];
bool dfs(int x){
      for(int i=0;i<v[x].size();i++){
          int u=v[x][i];
          if(!vis[u]){
            vis[u]=1;
            if(match[u]==-1||dfs(match[u])){
                match[u]=x;
               return true;
            }
          }
      }
      return false;
}
int main(){
     while(~scanf("%d",&t),t){
          scanf("%d%d",&n,&m);
          for(int i=1;i<=n;i++)v[i].clear();
          while(t--){
            int x,y;
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
          }
          int ans=0;
          memset(match,-1,sizeof(match));
          for(int i=1;i<=n;i++){
            memset(vis,0,sizeof(vis));
            if(dfs(i))ans++;
          }
          printf("%d
",ans);
     }
}
View Code

5839: 棋盘覆盖 返回顶部

描述

给定一个N行N列的棋盘,已知某些格子禁止放置。求最多能往棋盘上放多少块的长度为2、宽度为1的骨牌,骨牌的边界与格线重合(骨牌占用两个格子),并且任意两张骨牌都不重叠。N≤100。

输入

第一行为n,t(表示有t个删除的格子)
第二行到t+1行为x,y,分别表示删除格子所在的位置
x为第x行,y为第y列,行列编号从1开始。

输出

一个数,即最多能放的骨牌数

样例输入

 8 0

样例输出

 32

思路:

棋盘上一点的行列下标之和与其相邻四点的行列下标之和 奇偶性不同,因此可以按照行列下标之和的奇偶性将点集分成两个集合,点之间的相邻关系

就是集合间的关系,建图求最大匹配数

技术图片
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> p;
int n,t,a[105][105],ans;
p match[105][105];
bool vis[105][105];
int dtx[]={1,0,-1,0};
int dty[]={0,1,0,-1};
int get_id(int x,int y){
    return (x-1)*n+y;
}
bool check(int x,int y){
     if(x<1||y<1||x>n||y>n)return 0;
     if(a[x][y])return 0;
     return 1;
}
int dfs(int x,int y){
      for(int i=0;i<=3;i++){
           int X=x+dtx[i];
           int Y=y+dty[i];
           if(!check(X,Y))continue;
           if(!vis[X][Y]){
             vis[X][Y]=1;
             p e=match[X][Y];
             if(e.first<0||dfs(e.first,e.second)){
                 match[X][Y]=p(x,y);
                return 1;
             }
           }
      }
      return 0;
}
int main(){
      scanf("%d%d",&n,&t);
      for(int i=1;i<=t;i++){
          int x,y;
          scanf("%d%d",&x,&y);
          a[x][y]=1;
      }
      memset(match,-1,sizeof(match));
      for(int i=1;i<=n;i++){
          for(int j=1;j<=n;j++){
              if((i+j)%2==0&&!a[i][j]){
                  memset(vis,0,sizeof(vis));
                  if(dfs(i,j))ans++;
              }
          }
      }
      printf("%d
",ans);
}
View Code

5840: 車的放置 返回顶部

描述

给定一个N行M列的棋盘,已知某些格子禁止放置。问棋盘上最多能放多少个不能互相攻击的車。車放在格子里,攻击范围与中国象棋的“車”一致。N,M≤200。

输入

第一行为n,m,t(表示有t个禁止的格子)
第二行到t+1行为x,y,分别表示禁止格子所在的位置,x为第x行,y为第y列,行列编号从1开始。

输出

一个整数,表示最多能放多少个車。

样例输入

8 8 0

样例输出

8

思路:

将行和列分别作为两个集合,求二分图最大匹配数

技术图片
#include<bits/stdc++.h>
using namespace std;
int a[205][205],match[205],vis[205],n,m,t;
bool dfs(int x){
      for(int i=1;i<=m;i++){
          if(!a[x][i]&&!vis[i]){
            vis[i]=1;
            if(match[i]==0||dfs(match[i])){
                match[i]=x;
              return true;
            }
          }
      }
      return false;
}
int main(){
     scanf("%d%d%d",&n,&m,&t);
     while(t--){
        int x,y;
        scanf("%d%d",&x,&y);
        a[x][y]=1;
     }
     int ans=0;
     for(int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));
        if(dfs(i))
            ans++;
     }
     printf("%d
",ans);
}
View Code

5842: 骑士放置  返回顶部

描述

 给定一个 N*M 的棋盘,有一些格子禁止放棋子。问棋盘上最多能放多少个不能互相攻击的骑士(国际象棋的“骑士”,类似于中国象棋的“马”,按照“日”字攻击,但没有中国象棋“别马腿”的规则)。N, M<=100。

输入

第一行为n,m,t(表示有t个禁止的格子)
第二行到t+1行为x,y,分别表示禁止格子所在的位置,x为第x行,y为第y列,行列编号从1开始。 

输出

一个整数,表示最多能放多少个骑士。

样例输入

 2 3 0

样例输出

4

思路

骑士走日字,那么其下标x,y之和一定从偶数变为奇数,从奇数变为偶数,可当作二分图

最后求二分图最大独立集, 最大独立集 = 点数 - 最大匹配数 - 被禁止的点数

技术图片
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> p;
int n,m,t,a[105][105],ans;
p match[105][105];
bool vis[105][105];
int dtx[]={1,1,-1,-1,2,2,-2,-2};
int dty[]={2,-2,-2,2,1,-1,1,-1};
int get_id(int x,int y){
    return (x-1)*n+y;
}
bool check(int x,int y){
     if(x<1||y<1||x>n||y>m)return 0;
     if(a[x][y])return 0;
     return 1;
}
int dfs(int x,int y){
      for(int i=0;i<=7;i++){
           int X=x+dtx[i];
           int Y=y+dty[i];
           if(!check(X,Y))continue;
           if(!vis[X][Y]){
             vis[X][Y]=1;
             p e=match[X][Y];
             if(e.first<0||dfs(e.first,e.second)){
                 match[X][Y]=p(x,y);
                return 1;
             }
           }
      }
      return 0;
}
int main(){
      scanf("%d%d%d",&n,&m,&t);
      for(int i=1;i<=t;i++){
          int x,y;
          scanf("%d%d",&x,&y);
          a[x][y]=1;
      }
      memset(match,-1,sizeof(match));
      for(int i=1;i<=n;i++){
          for(int j=1;j<=m;j++){
              if((i+j)%2==0&&!a[i][j]){
                  memset(vis,0,sizeof(vis));
                  if(dfs(i,j))ans++;
              }
          }
      }
      printf("%d
",n*m-ans-t);
}
View Code

 

 

 

以上是关于图论:TZOJ二分图练习的主要内容,如果未能解决你的问题,请参考以下文章

图论之二分图-HihoCoder1121

图论 - 二分图基本概念

图论之二分图匹配

图论基础——二分图

图论基础——二分图

学习:图论----一般图