D e s c r i p t i o n Description Description
现在有一些道路,每个道路连接着两个路口,这些道路又被机构所管,现在问从零号点到一号点需要多少个机构,输出机构数以及字典序最小的方案
I n p u t Input Input
第一行三个整数k; n;m,分别表示机构数,路口数,以及街道的描述数。接下来m 行,每行三个整数a; b; c,表示机构c 管辖连接路口a,b的街道。
路口的编号范围为[0; n ? 1],机构的编号范围为[0; k ? 1]。贵族的家的编号为0,工作地点的编号为1。
O u t p u t Output Output
若有解,输出第一行一个整数ans,表示最少的通行证数,第二行ans个整数,表示所需通行证的编号。若有多种方案,请输出字典序最小的方案。若无解,输出"Impossible"。
S a m p l e Sample Sample I n p u t Input Input
3 3 3
0 2 0
0 2 1
1 2 2
S a m p l e Sample Sample O u t p u t Output Output
2
0 2
H i n t Hint Hint
2 <= n <= 30, 1 <= k <= 20。
T r a i n Train Train o f of of T h o u g h t Thought Thought
用dfs来做这一道题目(Code讲解)
C o d e Code Code
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int ans,answer[105],h[105],n,m,k;
bool c[35],d[35];
struct node
{
int to,g;
}w[35][105];
bool cmp(node i,node j){return i.g<j.g;}
void dfs(int dep,int sum)
{
if (sum>=ans) return;//没有更佳方案
if (dep==1)
{
if (sum<ans) //更佳
{
ans=0;
for (int i=0; i<k; ++i)
if (c[i])
answer[++ans]=i;//更新
}
else return;
}
d[dep]=true;
for (int i=1; i<=h[dep]; ++i)
{
if (!d[w[dep][i].to]) {
if (c[w[dep][i].g]) dfs(w[dep][i].to,sum);//这个机构已经贿赂过了
else {
c[w[dep][i].g]=true;
dfs(w[dep][i].to,sum+1);//继续往下找
c[w[dep][i].g]=false;
}
}
}
d[dep]=false;
}
int main()
{
freopen("license.in","r",stdin);
freopen("license.out","w",stdout);
scanf("%d%d%d",&k,&n,&m);
for (int i=1; i<=m; ++i)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
w[x][++h[x]].to=y;//to表示到达哪一个点
w[x][h[x]].g=z;//g表示机构
w[y][++h[y]].to=x;
w[y][h[y]].g=z;
}
for (int i=0; i<n; ++i)
sort(w[i]+1,w[i]+h[i]+1,cmp);
ans=2147483647;
dfs(0,0);
if (ans>=30) printf("Impossible");
else {
printf("%d\n",ans);
for (int i=1; i<=ans; ++i)
printf("%d ",answer[i]);
}
return 0;
}