1. 程式人生 > >無向圖點著色最優問題

無向圖點著色最優問題

題目:

連結:https://ac.nowcoder.com/acm/contest/215/B
來源:牛客網
給出一棵仙人掌(每條邊最多被包含於一個環,無自環,無重邊,保證連通),要求用最少的顏色對其頂點染色,滿足每條邊兩個端點的顏色不同,輸出最小顏色數即可

分析:

做了這題我才發現一個無向連通圖均可以在3種顏色內實現各點著色,並且當且僅當只有一個點的時候需要一種顏色,多個點的時候通過dfs和標記各點顏色情況來判斷是否需要三種顏色。

程式碼如下:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4
#include<queue> 5 #include<stack> 6 #include<vector> 7 #include<algorithm> 8 #define ll long long 9 using namespace std; 10 const int maxn=5e5+7; 11 int top,first[maxn],flag[maxn],flag1=0; 12 struct v 13 { 14 int to,next,val; 15 }edge[maxn*4]; 16 void init() 17 { 18 for
(int i=0;i<maxn;i++) 19 { 20 first[i]=-1; 21 } 22 top=0; 23 } 24 void edge_(int to,int go) 25 { 26 edge[top].to=go; 27 edge[top].next=first[to]; 28 first[to]=top++; 29 } 30 int dfs(int x) 31 { 32 for(int i=first[x];~i;i=edge[i].next) 33 { 34 int to=edge[i].to;
35 if(!flag[to]) 36 { 37 flag[to]=3-flag[x]; 38 if(!dfs(to)) 39 return 0; 40 } 41 else 42 { 43 if(flag[to]==flag[x])///判斷是否需要第三種顏色 44 { 45 return 0; 46 } 47 } 48 } 49 return 1; 50 } 51 int main() 52 { 53 init(); 54 int n,m; 55 scanf("%d%d",&n,&m); 56 for(int i=1;i<=m;i++) 57 { 58 int a,b; 59 scanf("%d%d",&a,&b); 60 edge_(a,b); 61 edge_(b,a); 62 } 63 if(n==1) 64 puts("1"); 65 else 66 { 67 for(int i=1;i<=n;i++) 68 { 69 if(!flag[i]) 70 { 71 flag[i]=1; 72 if(!dfs(i)) 73 { 74 puts("3"); 75 return 0; 76 } 77 } 78 } 79 puts("2"); 80 } 81 return 0; 82 }