http://acm.timus.ru/problem.aspx?space=1&num=1888
先分成幾個連通塊?? 然后枚舉每個點為起點? 計算它所在的連通塊以它為起點得到的差?(可能不存在)然后更新此連通塊的最大差
如果某個連通塊的最大差 不存在 則無解
如果每個連通塊的最大差都存在 則需要分兩種情況
如果只有一個連通塊? 則這個連通塊的最大差就是最終的最大差
如果有多個連通塊? 則最大差就是49? 因為每個聯(lián)通塊的起點不確定
代碼:
#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];//屬于第幾個聯(lián)通圖 int M[N],s[N],m;//m,有幾個聯(lián)通圖 s[]第幾個聯(lián)通圖最好以第幾個點為起點 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; }
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
