简单的操作

简单的操作

本题是个结论题,很容易猜出奇环是一定不行的,然后可以构造出一个二分图,我们发现对于一个点来说,可以将到它距离相等的点合并,所以最后一定可以合并成一条链
所以对每个点跑最短路就行了

#include
using namespace std;

const int N=1010,M=1e5+5;
int ss,n,m,head[N],vis[N],flag[N],tnt=0,cnt=0;
bool ex[N];
struct edge{
	int u,v,link;
}q[M<<1];
void put(int x,int y){
	q[++cnt].v=y;q[cnt].u=x;
	q[cnt].link=head[x];
	head[x]=cnt;
}
bool jh(int s,int num){
	vis[s]=num;
	bool flagg=false;
	for(int i=head[s];i;i=q[i].link){
		int v=q[i].v;
		if(vis[v]&&flag[s]==flag[v]){
			flagg=true;
			continue;
		}
		if(vis[v]) {continue;}
		flag[v]=(flag[s]^1);
		if(jh(v,num)){
			flagg=true;
		}
	}
	if(flagg ) return 1;
	return 0;
}
int dis[N][N],mxd[N];
void bfs(int x){
	queue<int> myline;
	myline.push(x);
	dis[ss][x]=0;
	memset(dis,0,sizeof(dis));
	memset(ex,0,sizeof(ex));
	ex[x]=1;
	 while(!myline.empty()){
	    int s=myline.front();myline.pop();
	    for(int i=head[s];i;i=q[i].link){
	   	int v=q[i].v;
		   if(!ex[v]){
		       ex[v]=1;
		       dis[x][v]=max(dis[x][v],dis[x][s]+1);
	   		   mxd[vis[x]]=max(mxd[vis[x]],dis[x][v]);
	   			myline.push(v);
	   		}
	   	 }
	   }
    }
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		put(u,v),put(v,u);
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			flag[i]=1;
			if(jh(i,++tnt)){
				puts("-1");
				exit(0);
			}
		}
	}
	for(int i=1;i<=n;i++){
		ss=i;
		bfs(i);
	}
	int ans=0;
	for(int i=1;i<=tnt;i++){
		ans+=mxd[i];
	}
	printf("%d",ans);
}

你可能感兴趣的:(例题,图论)