1. 程式人生 > >洛谷【P1692】——部落衛隊

洛谷【P1692】——部落衛隊

P1692 部落衛隊
洛谷

題目描述

原始部落byteland中的居民們為了爭奪有限的資源,經常發生衝突。幾乎每個居民都有他的仇敵。部落酋長為了組織一支保衛部落的隊伍,希望從部落的居民中選出最多的居民入伍,並保證隊伍中任何2 個人都不是仇敵。

給定byteland部落中居民間的仇敵關係,程式設計計算組成部落衛隊的最佳方案。

輸入輸出格式

輸入格式:
第1行有2個正整數n和m,表示byteland部落中有n個居民,居民間有m個仇敵關係。居民編號為1,2,…,n。接下來的m行中,每行有2個正整數u和v,表示居民u與居民v是仇敵。

輸出格式:
第1行是部落衛隊的頂人數;檔案的第2行是衛隊組成x i,1≤i≤n,xi =0 表示居民i不在衛隊中,xi=1表示居民i在衛隊中。

輸入輸出樣例

輸入樣例#1:
7 10
1 2
1 4
2 4
2 3
2 5
2 6
3 5
3 6
4 5
5 6
輸出樣例#1:
3
1 0 1 0 0 0 1
說明

60%資料:n<=20,m<=100

所有資料:n<=100,m<=3000

暴搜+剪枝

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[1001][1001],b[1000]={0},c[1000];
int max1=0,s,m;
void
shuchu(); int n; int dfs(int); int main() { int i1,x,y; cin>>n>>m; for(i1=1;i1<=m;i1++) { cin>>x>>y; a[x][y]=1; //第x個人的仇敵是第y個人 a[y][x]=1; //第y個人的仇敵是第x個人 } dfs(1); cout<<max1<<endl; for (int i1=1;i1<=n;i1++) //輸出
cout<<c[i1]<<" "; fclose(stdin);fclose(stdout); return 0; } int dfs(int k) { int i,j,c=0,v=0,z; for (i=1;i>=0;i--) if((v==0)&&(i==0)) break; //這裡是優化,判斷如果上一次該元素沒能入隊,那第二次判斷不進隊後的迴圈就沒有意義了,這裡作為一次優化。 else { z=0;c=0; if (i==1) //判斷這次進隊 { for (j=1;j<=k-1;j++) if (b[j]==1) if(a[j][k]==1) {c=1;break;} //判斷能否進隊,與之前已經進隊的元素是否有衝突 if (c==0) { b[k]=1; //標記該進隊元素 s++; //計數加一 v=1;//確定此次進隊了,標記一下 z=1; //確定此次進隊了,標記一下 }} if (k<n) dfs(k+1); //如果沒到邊界,遞迴深搜,進行下一個元素 else if (s>max1&&k==n) {shuchu();max1=s;} //否則則所有元素已經判斷進隊完畢,則判斷此次計數是否最大值,並交換,覆蓋最優解 if (z==1) s--; //回溯 b[k]=0; //回溯 } } void shuchu() { for(int i=1;i<=n;i++) c[i]=b[i]; //覆蓋最優解 }