1. 程式人生 > >[bzoj4878][DFS]挑戰NP-Hard

[bzoj4878][DFS]挑戰NP-Hard

Description

天才大學生quailty熱衷於解決NP-Hard問題,你如果AC 了這道題,就可以成為他真正的粉絲。圖染色問題:給定
無向圖G和一個正整數k。對於圖中的每個點,選擇一個在[1,k]之間的整數作為其顏色。你需要保證對於每條邊,
其兩端點的顏色均不相同。簡單k路徑問題:給定無向圖G和一個正整數k。請找到一條經過了恰好k條邊的簡單路徑
。即,你需要找到一個長度為k+1的序列v_1,v_2,…,v_{k+1},滿足1<=v_i<=n,且任意兩個v均不相同,同時v_i
與v_{i+1}之間存在一條邊。現在給定無向圖G和一個正整數k,quailty知道你沒有他的水平,所以你只需解決上面
的任意一個問題就可以成為他的粉絲。

Input

第一行包含一個正整數T(1<=T<=1000),表示測試資料的組數。
對於每組資料,第一行包含三個正整數n,m,k(1<=n<=1000,1<=m<=10000,1<=k<=n),分別表示圖的點數與邊數。
接下來m行,每行兩個正整數a,b(1<=a,b<=n),表示a到b之間存在一條無向邊。
輸入資料保證不存在重邊與自環,且總邊數不超過100000。

Output

對於每組資料: 若選擇了圖染色問題,請輸出“color”,然後輸出n個在1到k之間的正整數,分別表示每個點的顏色。
若選擇了簡單路徑問題,請輸出“path”,然後輸出k+1個在1到n之間的正整數,分別表示路徑上每個點的編號。 若有多組可行解,輸出任意一組。

Sample Input

2

4 5 2

1 2

2 3

3 4

4 1

1 3

3 3 3

1 2

2 3

3 1

Sample Output

path 3 2 1

color 1 2 3

題解

有點東西…
我們需要注意到一個東西:在無向圖的DFS樹上是隻存在有返祖邊而不存在有橫插邊的
對這個圖做出DFS樹
顯然如果深度>=K的話我們總可以找到一條長度為K的路徑
否則把點的顏色設為深度就好了
因為同層的不會有邊,有邊的只會在異層中出現
注意圖可能不聯通

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{
	int f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int stack[20];
inline void write(LL x)
{
	if(x<0){putchar('-');x=-x;}
    if(!x){putchar('0');return;}
    int top=0;
    while(x)stack[++top]=x%10,x/=10;
    while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(LL x){write(x);putchar('\n');}
const int MAXN=1005;
const int MAXM=20005;
struct node{int x,y,next;}a[MAXM];int len,last[MAXN];
void ins(int x,int y){len++;a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;}
int vis[MAXN],dep[MAXN],fa[MAXN];
int n,m,K;
void dfs(int x)
{
	vis[x]=1;
	for(int k=last[x];k;k=a[k].next)
	{
		int y=a[k].y;
		if(!vis[y])dep[y]=dep[x]+1,fa[y]=x,dfs(y);
	}
}
int main()
{
	int T=read();while(T--)
	{
		n=read();m=read();K=read();
		len=0;memset(last,0,sizeof(last));
		for(int i=1;i<=m;i++)
		{
			int x=read(),y=read();
			ins(x,y);ins(y,x);
		}
		memset(vis,0,sizeof(vis));
		for(int i=1;i<=n;i++)if(!vis[i])dep[i]=0,dfs(i);
		int mx=0;
		for(int i=1;i<=n;i++)mx=max(mx,dep[i]);
		if(mx>=K)
		{
			printf("path ");
			int u=-1;
			for(int i=1;i<=n;i++)if(dep[i]>=K){u=i;break;}
			while(K--)pr1(u),u=fa[u];
			pr2(u);
		}
		else
		{
			printf("color ");
			for(int i=1;i<n;i++)pr1(dep[i]+1);
			pr2(dep[n]+1);
		}
	}
	return 0;
}