Colourful Graph 2016香港

tech2022-07-27  149

https://open.kattis.com/problems/colourful

实际上用一棵树的边就行了,如果原树每种目标树有点颜色都有,那么就一定能行

那么把一棵树抠出来,然后某一种颜色少了,就随便找到一个点,然后再随便找一些比目标数多的颜色的点,一路交换到这个点旁边,然后把多的点变成这个少了的颜色

颜色数量一样后,再按照先序遍历的顺序,一个点一个点地安排,按先序遍历的目的是,已经搞好的子树就不用再移动他们了。

最多n个点颜色不一样,交换颜色数量最多n次,所以统一颜色数最多用10000次。然后一个点一个点地安排,每次最多交换n个点,那么也是最多用10000次,上限刚好200000次

代码格式有点难看,用emacs写的,交上去就成这样了。。

#include<bits/stdc++.h> using namespace std; const int maxl=110; int n,m,k,flag,ans,ansv; int a[maxl],ta[maxl],num[maxl],tnum[maxl]; int frm[maxl]; bool vis[maxl]; vector<int> e[maxl],ee[maxl],b; inline void predfs(int u) { vis[u]=true; for(int v:ee[u]) if(!vis[v]) { e[u].push_back(v); e[v].push_back(u); predfs(v); } b.push_back(u); } inline void prework() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) scanf("%d",&a[i]),num[a[i]]++; for(int i=1;i<=n;i++) scanf("%d",&ta[i]),tnum[ta[i]]++; int u,v; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); ee[u].push_back(v); ee[v].push_back(u); } predfs(1); } inline void print() { for(int i=1;i<=n;i++) printf("%d%c",a[i]," \n"[i==n]); } inline void dfs(int u) { vis[u]=true; if(num[a[u]]>tnum[a[u]]) { ansv=u; return; } for(int v:e[u]) if(!vis[v]) { frm[v]=u; dfs(v); if(ansv) return; } } inline void findcol(int u,int col) { vis[u]=true; if(a[u]!=ta[u] && a[u]==col) { ansv=u; return; } for(int v:e[u]) if(!vis[v]) { frm[v]=u; findcol(v,col); if(ansv) return; } } inline void mainwork() { ans=1; for(int i=0;i<k;i++) if(tnum[i]>0 && num[i]==0) ans=0; if(!ans) { puts("Impossible"); return; } print(); int u,v; for(int i=0;i<k;i++) if(num[i]<tnum[i]) { for(int j=1;j<=n;j++) if(a[j]==i) {u=j;break;} while(num[i]<tnum[i]) { for(int j=1;j<=n;j++) frm[j]=0,vis[j]=false; ansv=0; dfs(u);v=ansv; while(frm[v]!=u) { swap(a[v],a[frm[v]]); v=frm[v];print(); } num[a[v]]--;num[i]++; a[v]=i;print(); } } for(int d:b) if(a[d]!=ta[d]) { for(int i=1;i<=n;i++) frm[i]=0,vis[i]=false; ansv=0; findcol(d,ta[d]);v=ansv; while(v!=d) { swap(a[v],a[frm[v]]); v=frm[v];print(); } } } int main() { prework(); mainwork(); return 0; }

 

 

最新回复(0)