Continuous attack game [P1640] Luo Gu bipartite graph matching deformation of the [good] [each title memset too slow, with a time stamp id. ]

lxhgww recently fell in love with a game, in the game, he has a lot of equipment, each equipment has two properties, the values ​​of these properties with the number between [1,10000] representation. When he uses some equipment, he can only use one attribute of the equipment. And can only be used at most once for each equipment. Game to the last, lxhgww met the ultimate boss, the ultimate boss is very strange, property values ​​used to attack his equipment must continuously increasing attack from start 1, in order to harm the boss. That is the beginning of time, lxhgww can only use one attack boss property and equipment value of 1, and then only use the value of a property, equipped with attack boss 2, and then only use the value of a property and equipment 3 attack boss ...... and so on. Now he wants to know lxhgww up to attack a boss How many times?

Input Format

The first line of the input N is an integer, N denotes lxhgww kinds of equipment has N rows Next, N is the description of these kinds of equipment, each row two numbers indicate two attribute values ​​of the i-th equipment

Output Format

Output line, comprising a number representing the number of continuous attacks lxhgww up.

Sample input and output

Input # 1
3
1 2
3 2
4 5
Output # 1
2

Description / Tips

Limitation

For 30% of the data, to ensure that N <= 1000

To 100% of the data, to ensure that N <= 1000000

Source: SCOI 2010

【to sum up】

Bipartite graph maximum matching problem, the approach is very clever, but it is difficult to think of.

At first glance this question is to think of an item of property is divided into two section around the point, but it is difficult to solve this problem, especially when dealing with an item only when one attribute. Therefore, we wish to change an idea for an article  i i attributes  A, B A , B, respectively, from  A A and  B B to  i has a directed edge i connected. The property items as the left part of the point, as the right part of the point number, you can find the maximum matching.

Why is this correct? We can consider the specific process Hungarian algorithm: the matching value  i when i skills, then  1 i-1 i - 1 property must have matching complete, so if  i i corresponding number  J J is matched words, so let matching  j j that attributes  the p- the p-label look for other matching items, figuratively speaking, is to use other items to release the attack as  the p- the p-this skill, with  j release this article to attack j  i i skills. If you find such an augmenting path, then it shows the current match, ans ++.

[Harvest]: Every time memset too slow, with a time stamp id.

AC Code: [link] matrix

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 #define maxn 1000009
 5 int now;
 6 inline int read(){
 7     char c = getchar(); int x = 0, f = 1;
 8     while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
 9     while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
10     return x * f;
11 }
12 int match[maxn];
13 int vis[maxn];
14 struct Edge{
15     int to;
16     int next;
17 }e[3*maxn];
18 int cnt=1;
19 int head[maxn];
20 void add(int u,int v){
21     e[cnt].to=v;
22     e[cnt].next=head[u];
23     head[u]=cnt++;
24 }
25 int dfs(int u){
26     int temp;
27     for(int i=head[u];i;i=e[i].next){
28         temp=e[i].to;
29         if(vis[temp]!=now){
30             vis[temp]=now;
31         //    vis[temp]=1;
32             if(match[temp]==0||dfs(match[temp])){
33                 match[temp]=u;
34                 return 1;
35             }
36         }
37     }
38     return 0;
39 }
40 int main(){
41     int n;int x,y;
42     //scanf("%d",&n);
43     n=read();
44     for(int i=1;i<=n;i++){
45         x=read();
46         y=read();
47         add(x,i);
48         add(y,i);
49     } 
50     int ans=0;
51     for(int i=1;i<=n;i++){
52         now++;
53         if(dfs(i))
54             ans++;
55         else{
56             break;
57         }
58     }
59     printf("%d\n" , Year);
 60      return  0 ;
 61 }

 

[Vector] FIG deposit

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 #define maxn 1000009
 5 int match[maxn];
 6 int vis[maxn];
 7 int id;
 8 vector<int> v[maxn];
 9 int dfs(int u){
10     for(int i=0;i<v[u].size();i++){
11         int temp=v[u][i];
12         if(vis[temp]!=id){
13             vis[temp]=id;
14             if(match[temp]==0||dfs(match[temp])){
15                 match[temp]=u;
16                 return 1;
17             }
18         }
19     }
20     return 0;
21 }
22 int main(){
23     int n;
24     scanf("%d",&n);
25     for(int i=1;i<=n;i++){
26         int x,y;
27         scanf("%d%d",&x,&y);
28         v[x].push_back(i);
29         v[y].push_back(i);
30     } 
31     memset(match,0,sizeof(match));
32     int ans=0;
33     for(int i=1;i<=n;i++){
34         id++;
35         if(dfs(i))
36             ans++;
37         else{
38             break;
39         }
40     }
41     cout<<ans<<endl;
42     return 0;
43 }

 

 

Guess you like

Origin www.cnblogs.com/pengge666/p/11627542.html