树上差分的代码很简洁,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 ");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 %d ",self_tmp);} 71 else{printf("%d ",m);for(int i=1;i<m;i++)printf("%d ",i);printf("%d ",m);} 72 return; 73 } 74 if(self_tmp){printf("0 ");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 ",ans.size()); 81 for(int i=0;i<ans.size();i++){ 82 printf("%d",ans[i]); 83 if(i==ans.size()-1)printf(" "); 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 }