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; }