COCI2014 / 2015 Contest # 1 D MAFIJA [ring] independent sets the maximum tree

T1725 天黑请闭眼

Judge Online : COCI2014 / 2015 Contest The # 1 D MAFIJA (original title)

The Label : ring tree, a tree-off ring + Dp, greedy topology +

Title Description

Recently天黑请闭眼very popular in country C! The game has two identities, is a killer, the other is a civilian. I know who the killer is a killer, and civilians knew nothing about. Now in order to know who the killer is, everyone involved in the game have to testify against a man-killer, it is certain that the killer will testify against civilians , and civilians to testify of who might be the killer, there may be civilians. Each person is given the players to testify, please find the largest possible number of game killer.

Entry

The first line contains an integer N, the number of players. Players are numbered 1 ~ N.

Next N lines, each an integer, wherein the number of lines that number is K K player is referred killer player card number.

The test point in each line of output, if the conditions are satisfied or output No. outputs Yes

Export

Output line only, it may represent up to the number of the killer.

Sample

Input

7
3
3
4
5
6
4
4

3
2
3
1

3
2
1
1

Output

4

1

2

Hint

100% data N <= 500000.

answer

Although the subject is directed to the side, but in fact the equivalent of two-way side. And for edge \ ((U, v) \) , just make sure that between the two at most only a killer.

prove:

For the edge u-> v, there is only the meaning of the questions emulated \ ((U =. 1, V = 0), (U = 0, V =. 1), (U = 0, V = 0) \) ;

For the side v-> u, there is only similar to the emulated \ ((v = 0, u = 1), (v = 0, u = 0), (v = 1, u = 0) \)

Analysis finishing obtained, irrespective of the longitudinal direction, between two points connected to only take up a killer .

The title becomes a demand 基环树上的最大独立集.


A practice

Reminiscent of a similar classic tree Dp topic - no party boss .

Compared to this question is a tree ring, more than one ring, but may not communicate with FIG. But there is an important discovery: each block communication, and has only one ring .

Taking into account the common routine of tree ring - the ring off, and then turn the tree problem is solved.

Q1: how off the ring?

Using disjoint-set to maintain the connectivity of the dots, the front edge of the set have been combined in the same record. At that time when dfs, you can avoid this edge.

Q2: how do after breaking the ring?

Broken after the ring formation of a regular tree, the tree directly to Dp (that is the upper channel approach). But note that our record of broken edge \ ((u, v) \ ) both can not take a killer at the same time. How convenient solution than? Direct respectively \ (u, v \) for the dfs root or twice can finally \ (max (dp [u] [0], dp [v] [0]) \) accumulated to answer (as it may be communication with a plurality of blocks).

The time complexity of the algorithm is \ (O (N) \) .

code show as below:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
inline int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x;
}

struct edge{
    int to,nxt;
}e[2*N];
int n,head[N],cnt;
inline void link(int u,int v){
    e[++cnt].to=v,e[cnt].nxt=head[u];
    head[u]=cnt;
}
int tot,fa[N],u[N],v[N],id[N];
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int dp[N][2];
void dfs(int x,int f,int ban){
    dp[x][0]=0,dp[x][1]=1;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==f||i==ban||i==ban-1)continue;
        dfs(y,x,ban);
        
        dp[x][0]+=max(dp[y][0],dp[y][1]);
        dp[x][1]+=dp[y][0];
    }
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=n;i++){
        int to=read();  
        link(i,to);link(to,i);
        int A=find(i),B=find(to);
        if(A==B){//去除环上的某条边 
            u[++tot]=i,v[tot]=to,id[tot]=2*i;
        }
        else fa[A]=B;
    }
    
    int ans=0;
    for(int i=1;i<=tot;i++){
        dfs(u[i],0,id[i]);
        int tmp1=dp[u[i]][0];
        dfs(v[i],0,id[i]);
        int tmp2=dp[v[i]][0];
        ans+=max(tmp1,tmp2);
    }
    printf("%d\n",ans);
}

Practice two

Obtaining an ring tree (also for general tree) maximum independent set of points on ( without weight ), there is such a greedy scheme.

For a 0-degree point of \ (the X-\) (here we re treated as a one-way side edge), which points to \ (to [x] \) , then obviously the \ (to [x] \) Black is excellent, it is possible to use dfs similar topology to the point marking the last meter number.

#include<bits/stdc++.h>
using namespace std;
const int N=500010;
int n,ans=0,to[N],ing[N];
bool mark[N]; 
void dfs(int x,int w){
    if(mark[x])return;
    mark[x]=1;
    if(w)ans++;
    ing[to[x]]--;
    if(ing[to[x]]==0||w==1)dfs(to[x],!w);   
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&to[i]),ing[to[i]]++;
    for(int i=1;i<=n;i++)if(!ing[i])dfs(i,1);
    for(int i=1;i<=n;i++)if(!mark[i])dfs(i,0);
    printf("%d\n",ans);
}

Time complexity of both are \ (O (N) \) , but the first contrast-off ring dp + tree approach more promotional, applies to point to the right - for example, the following a few questions:

[ZJOI2008] Knight

HDU4830 Party

Guess you like

Origin www.cnblogs.com/Tieechal/p/11522006.html