題目連接:(https://zoj.pintia.cn/problem-sets/91827364500/problems/91827370504)(https://vjudge.net/problem/ZOJ-4109)ios
題面複製不過來。spa
題意:n我的,編號爲1~n,m個朋友關係(a和b是朋友,a和c是朋友不表明b和c是朋友),將n我的按照順序排好,若是一我的前面沒有他的朋友那麼不滿意度加一,讓你給出一個排序使得不滿意度最小化,有相同結果的排序輸出字典序最小的那個。.net
有關係存在,考慮畫圖。畫完圖後發現不滿意度的最小值便是圖的連通份量的個數,由於每當選定一個連通份量的的人進入序列,與他鏈接的人就能夠都順着鏈接加入序列,從而不會增長不滿意度。求連通份量個數可用並查集實現。code
要求輸出字典序最小的,想到了用優先隊列實現的bfs,優先選擇隊列中編號最小的點。blog
由於用memset致使超時好幾回,初始化時最好用多少初始化多少。排序
代碼:隊列
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <queue> 6 typedef long long ll; 7 using namespace std; 8 9 const int N=1e6+5; 10 11 struct cmp { 12 bool operator()(int a,int b) { 13 return a>b; 14 } 15 }; 16 17 priority_queue <int,vector <int>,cmp> Q; 18 19 int E[N<<1],fir[N],nex[N<<1],tot; 20 int per[N]; 21 bool vis[N]; 22 bool book[N]; 23 int n,m,cnt; 24 25 void init() { 26 for(int i=1;i<=n;i++) { 27 per[i]=i;fir[i]=-1;vis[i]=false;book[i]=false; 28 } 29 cnt=tot=0; 30 } 31 32 void connect(int from,int to) { 33 E[tot]=to; 34 nex[tot]=fir[from]; 35 fir[from]=tot++; 36 E[tot]=from; 37 nex[tot]=fir[to]; 38 fir[to]=tot++; 39 } 40 41 int root(int x) { 42 int tempa,tempb; 43 tempa=x; 44 while(x!=per[x]) x=per[x]; 45 while(per[tempa]!=x) { 46 tempb=per[tempa]; 47 per[tempa]=x; 48 tempa=tempb; 49 } 50 return x; 51 } 52 53 void merge(int x,int y) { 54 int t1=root(x); 55 int t2=root(y); 56 if(t1!=t2) { 57 per[t1]=t2;cnt++; 58 } 59 } 60 61 void solve() { 62 int cnt=0; 63 while(!Q.empty()) { 64 int q=Q.top();Q.pop(); 65 if(vis[q]) continue; 66 vis[q]=true; 67 cnt++; 68 printf("%d",q); 69 if(cnt!=n) printf(" "); 70 for(int i=fir[q];i!=-1;i=nex[i]) { 71 int to=E[i]; 72 if(!vis[to]) Q.push(to); 73 } 74 } 75 printf("\n"); 76 } 77 78 int main() { 79 int t; 80 scanf("%d",&t); 81 while(t--) { 82 scanf("%d%d",&n,&m); 83 init(); 84 for(int i=1;i<=m;i++) { 85 int x,y; 86 scanf("%d%d",&x,&y); 87 connect(x,y); 88 merge(x,y); 89 } 90 printf("%d\n",n-cnt); 91 for(int i=1;i<=n;i++) { 92 if(!book[root(i)]) { 93 book[root(i)]=true; 94 Q.push(i); 95 } 96 } 97 solve(); 98 } 99 return 0; 100 }