洛谷【P1692】——部落衛隊
阿新 • • 發佈:2019-02-07
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]; //覆蓋最優解
}