BZOJ4424: Cf19E Fairy

树上差分的代码很简洁,dfs+差分即可

这题很多坑点啊,比如重边自环好坑

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #define pii pair<int,int>
 7 #define pb push_back
 8 #define mp make_pair
 9 #define ft first
10 #define sc second
11 #define MAXN 1000000+10
12 using namespace std;
13 int first[MAXN],edges[MAXN<<1],nxt[MAXN<<1],to[MAXN<<1];
14 int n,m,c=-1;
15 int b[MAXN],d[MAXN],tag[MAXN];
16 int tmp,cnt,self_tmp;
17 void insert(int x,int y,int e){
18     nxt[++c]=first[x],first[x]=c,to[c]=y,edges[c]=e;
19     nxt[++c]=first[y],first[y]=c,to[c]=x,edges[c]=e;
20 }
21 void init(){
22     scanf("%d%d",&n,&m);
23     int x,y;
24     for(int i=1;i<=m;i++){
25         scanf("%d%d",&x,&y);
26         if(x==y&&!self_tmp){self_tmp=i;continue;}
27         if(x==y){self_tmp=-1;continue;}
28         insert(x,y,i);
29     }
30 }
31 void dfs(int x,int fa){
32     for(int e=first[x];e;e=nxt[e]){
33         if(e==(fa^1))continue;
34         int &y=to[e];
35         if(d[y]){
36             if(d[x]<d[y])continue;
37             if((d[x]-d[y]+1)&1){
38                 tag[x]++,tag[y]--;
39                 cnt++;tmp=edges[e];
40             }
41             else{
42                 tag[x]--,tag[y]++;
43             }
44         }
45         else{
46             d[y]=d[x]+1;
47             dfs(y,e);
48             tag[x]+=tag[y];
49         }
50     }
51 }
52 vector<int> ans;
53 void find(int x){
54     b[x]=1;
55     for(int e=first[x];e;e=nxt[e]){
56         int &y=to[e];
57         if(b[y])continue;
58         if(tag[y]==cnt){
59             ans.pb(edges[e]);
60         }
61         find(y);
62     }
63 }
64 void solve(){
65     if(-1==self_tmp){printf("0\n");return;}
66     for(int i=1;i<=n;i++){
67         if(!d[i])d[i]=1,dfs(i,0);
68     }
69     if(!cnt){
70         if(self_tmp){printf("1\n%d\n",self_tmp);}
71         else{printf("%d\n",m);for(int i=1;i<m;i++)printf("%d ",i);printf("%d\n",m);}
72         return;
73     }
74     if(self_tmp){printf("0\n");return;}
75     for(int i=1;i<=n;i++){
76         if(!b[i])find(i);    
77     }
78     if(cnt==1)ans.pb(tmp);
79     sort(ans.begin(),ans.end());
80     printf("%d\n",ans.size());
81     for(int i=0;i<ans.size();i++){
82         printf("%d",ans[i]);
83         if(i==ans.size()-1)printf("\n");
84         else printf(" ");
85     }
86 }
87 int main()
88 {
89 //  freopen("data.in","r",stdin);  
90 //  freopen("my.out","w",stdout);  
91     init();
92     solve();
93     return 0;
94 }
View Code

 

posted @ 2018-01-09 01:02  white_hat_hacker  阅读(991)  评论(0编辑  收藏  举报