题意:
K种护照,N个地点,M条路,每条路通行都要一种护照
求最少护照数量
枚举所需的护照种类
dfs搜索
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
#define cler(arr, val) memset(arr, val, sizeof(arr))
typedef long long LL;
const int MAXN = 60;
const int MAXM = 11111;
const int INF = 0x3f3f3f3f;
int k,n,m,ans,vis[MAXN];
LL xx,mp[MAXN][MAXN];
int dfs(int u,int fa,LL s)
{
if(u==1) return 1;
if(vis[u]) return 0;
vis[u]=1;
for(int i=1;i<n;i++)
{
if(s&mp[u][i])
{
if(dfs(i,u,s))
return 1;
}
}
return 0;
}
int main()
{
int x,y,z;
cin>>k>>n>>m;
ans=INF;
cler(mp,0);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&z);
mp[x][y]|=(1<<z);
mp[y][x]=mp[x][y];
}
vis[0]=1;
for(LL i=0;i<(1<<k);i++)
{
LL temp=i,num=0;
while(temp)
{
if(temp&1) num++;
temp>>=1;
}
if(ans<=num) continue;
cler(vis,0);
if(dfs(0,-1,i))
{
ans=num;
xx=i;
}
}
int flag=0;
cout<<ans<<endl;
for(int i=0;i<k;i++)
if(xx&(1<<i))
{
if(flag) printf(" ");
flag=1;
printf("%d",i);
}
puts("");
return 0;
}
/*
*/