刚学OI三天的蒟蒻求助/kk
  • 板块CF19E Fairy
  • 楼主muyang_233
  • 当前回复2
  • 已保存回复2
  • 发布时间2021/8/14 11:13
  • 上次更新2023/11/4 10:43:18
查看原帖
刚学OI三天的蒟蒻求助/kk
113521
muyang_233楼主2021/8/14 11:13

rt,树上差分,也考虑了连通性问题,WA on #23
output:

1  
2729

code:

#include <queue>
#include <cstdio>
using namespace std;
#define debug puts("qaq")
struct edge{
	int v,last,yuanlai;
}edge[20005],tree[20005];
int n,m;
int cnt;
int ecnt;
int tcnt;
int d[10005];
int p[10005];
int pt[10005];
int iu[10005];
int iv[10005];
bool vis[10005];
int color[10005];
int depth[10005];
int f[10005][25];
bool is_on_tree[20005];
priority_queue<int,vector<int>,greater<int> > pq;
inline void init(){
	for (int i=1;i<=n;i++){
		p[i]=pt[i]=color[i]=depth[i]=-1;
	}
}
inline void add(int u,int v){
	edge[++ecnt].v=v;
	edge[ecnt].last=p[u];
	p[u]=ecnt;
}
inline void addt(int u,int v,int yl){
	tree[++tcnt].v=v;
	tree[tcnt].last=pt[u];
	tree[tcnt].yuanlai=yl;
	pt[u]=tcnt;
}
void dfs(int u,int nc){
	color[u]=nc;
	for (int i=p[u];i!=-1;i=edge[i].last){
		int v=edge[i].v;
		if (color[v]==-1){
			dfs(v,1-nc);
			is_on_tree[i]=true;
			if (u<v) is_on_tree[i+1]=true;
			else is_on_tree[i-1]=true;
			addt(u,v,(i+1)/2);addt(v,u,(i+1)/2);
		}
	}
}
void dfs2(int u,int fa){
	f[u][0]=fa;depth[u]=depth[fa]+1;
	for (int j=1;j<=18;j++){
		f[u][j]=f[f[u][j-1]][j-1];
	}
	for (int i=pt[u];i!=-1;i=tree[i].last){
		int v=tree[i].v;
		if (v!=fa){
			dfs2(v,u);
//			printf("%d->%d\n",u,v);
		}
	}
}
inline int lca(int u,int v){
	if (depth[u]<depth[v]){
		int t=u;u=v;v=t;
	}
	int j=18;
	while(j>=0){
		if (depth[f[u][j]]>=depth[v]){
			u=f[u][j];
		}
		--j;
	}
	if (u==v){
		return u;
	}
	for (j=18;j>=0;j--){
		if (f[u][j]!=f[v][j]){
			u=f[u][j];v=f[v][j];
		}
	}
	return f[u][0];
}
bool dfs3(int u,int fa){
	vis[u]=true;
	for (int i=pt[u];i!=-1;i=tree[i].last){
		int v=tree[i].v;
		if (v!=fa){
//			printf("%d->%d:%d\n",u,v,res+d[u]);
			bool qwq=dfs3(v,u);
			d[u]+=d[v];
			if (qwq){
				pq.push(tree[i].yuanlai);
			}
		}
	}
//	printf("d[%d]=%d\n",u,d[u]);
	return d[u]==cnt;
}
int main(){
	scanf("%d%d",&n,&m);
	init();
	for (int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		if (u>v){
			int t=u;u=v;v=t;
		}
		iu[i]=u;iv[i]=v;
		add(u,v);add(v,u);
	}
	for (int i=1;i<=n;i++){
		if (color[i]==-1){
			dfs(i,0);
		}
	}
	/*
	for (int i=1;i<=n;i++){
		printf("color[%d]=%d\n",i,color[i]);
	}
	//*/
	for (int i=1;i<=n;i++){
		if (depth[i]==-1){
			dfs2(i,0);
		}
	}
//	debug;
	for (int i=1;i<=m;i++){
		if (!is_on_tree[2*i]){
			if (color[iu[i]]==color[iv[i]]){
				if (!cnt) pq.push(i);
				++cnt;
				int nu=iu[i];
				int nv=iv[i];
				if (depth[nu]<depth[nv]){
					int t=nu;nu=nv;nv=t;
				}
				int L_C_A=lca(nu,nv);
				if (L_C_A==nv){
					d[nu]++;d[nv]--;
				}
				else{
					d[nu]++;d[nv]++;
					d[L_C_A]--;
					
				}
			}
		}
	} 
	/*
	for (int i=1;i<=n;i++){
		printf("d[%d]=%d\n",i,d[i]);
	}
	printf("%d\n",cnt);
	//*/
	if (!cnt){
		printf("%d\n",m);
		for (int i=1;i<=m;i++){
			printf("%d ",i);
		}
	}
	else{
		if (cnt!=1)  pq.pop();
		for (int i=1;i<=n;i++){
			if (!vis[i]){
				dfs3(i,0);
			}
		}
		printf("%d\n",pq.size());
		while(!pq.empty()){
			printf("%d ",pq.top());
			pq.pop();
		}
	}
	return 0;
}

2021/8/14 11:13
加载中...