http://acm.timus.ru/problem.aspx?space=1&num=1888
先分成几个连通块 然后枚举每个点为起点 计算它所在的连通块以它为起点得到的差 (可能不存在)然后更新此连通块的最大差
如果某个连通块的最大差 不存在 则无解
如果每个连通块的最大差都存在 则需要分两种情况
如果只有一个连通块 则这个连通块的最大差就是最终的最大差
如果有多个连通块 则最大差就是49 因为每个联通块的起点不确定
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<cmath>
#define LL long long
#define sint short int
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const int N=105;
const int INF=0x3f3f3f3f;
int head[N],I;
struct node
{
int j,next;
}side[N*N];
int d[N];//等级
int v[N];//属于第几个联通图
int M[N],s[N],m;//m,有几个联通图 s[]第几个联通图最好以第几个点为起点 M[]最大差距
void add(int i,int j)
{
side[I].j=j;
side[I].next=head[i];
head[i]=I++;
}
void dfs(int x,int k)
{
v[x]=k;
for(int t=head[x];t!=-1;t=side[t].next)
{
int j=side[t].j;
if(v[j]==-1)
{
dfs(j,k);
}
}
}
int bfs(int x1,int st)
{
queue<int>qt;
qt.push(x1);
d[x1]=st;
int k=0;
while(!qt.empty())
{
int x=qt.front();
qt.pop();
k=max(k,d[x]);
for(int t=head[x];t!=-1;t=side[t].next)
{
int j=side[t].j;
if(v[j]!=v[x])
continue;
if(d[j]!=0&&abs(d[j]-d[x])!=1)
return -1;
if(d[j]!=0&&abs(d[j]-d[x])==1)
continue;
d[j]=d[x]+1;
qt.push(j);
}
}
return (k-st);
}
int main()
{
//freopen("data.in","r",stdin);
int n,p;
while(cin>>n>>p)
{
memset(head,-1,sizeof(head));
I=0;
while(n--)
{
int l,r;
cin>>l>>r;
add(l,r);
add(r,l);
}
memset(v,-1,sizeof(v));
m=0;
for(int i=1;i<=p;++i)
if(v[i]==-1)
dfs(i,m++);
memset(M,-1,sizeof(M));
memset(s,-1,sizeof(s));
for(int i=1;i<=p;++i)
{
memset(d,0,sizeof(d));
int k=bfs(i,1);
if(k!=-1)
{
int l=v[i];
if(k>M[l])
{M[l]=k;s[l]=i;}
}
}
bool flag=true;
for(int i=0;i<m;++i)
if(M[i]==-1)
flag=false;
if(flag==false)
{cout<<"-1"<<endl;continue;}
memset(d,0,sizeof(d));
if(m==1)
{
cout<<M[0]<<endl;
bfs(s[0],1);
}else
{
cout<<"49"<<endl;
bfs(s[0],1);
for(int i=1;i<m;++i)
bfs(s[i],50-M[i]);
}
for(int i=1;i<=p;++i)
cout<<d[i]<<" ";
cout<<endl;
}
return 0;
}
浙公网安备 33010602011771号