通行证
jzoj 2013
题目大意:
有一个图,走某一条路需要某个通行证(数据给出所有可选择的),现在要从某个点到另一个点,问最少要多少个通行证
样例输入
3 3 3
0 2 0
0 2 1
1 2 2
样例输出
2
0 2
数据范围限制
2 <= n <= 30, 1 <= k <= 20。
解题思路:
直接走每一条路,然后要通行证的就记录下来,最后看看那一条路用到的通行证最少
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int k,n,m,x,y,z,tot,ans,s[50],p[50],pp[50],num[50];
struct rec
{int to,t;
}a[50][50];
void dfs(int dep,int now)
{if (now>=ans) return;if (dep==1)//到了{if (now<ans)//更优{ans=0;for (int i=0;i<k;++i)if (p[i])//要用的s[++ans]=i;}return;}pp[dep]=1;for (int i=1;i<=num[dep];++i)if (!pp[a[dep][i].to])//没有重复到一个点if (p[a[dep][i].t]) dfs(a[dep][i].to,now);//这个通行证已经有了else{p[a[dep][i].t]=1;//记录dfs(a[dep][i].to,now+1);//dfsp[a[dep][i].t]=0;//清零}pp[dep]=0;
}
bool cmp(rec xx,rec yy){return xx.t<yy.t;}
int main()
{scanf("%d %d %d",&k,&n,&m);for (int i=1;i<=m;++i){scanf("%d %d %d",&x,&y,&z);a[x][++num[x]].to=y;//记录到达的点a[x][num[x]].t=z;//记录通行证编号a[y][++num[y]].to=x;a[y][num[y]].t=z;}for (int i=0;i<n;++i)sort(a[i]+1,a[i]+1+num[i],cmp);//排序,保证字典序ans=2147483647;dfs(0,0);if (ans<50){printf("%d\n",ans);for (int i=1;i<=ans;++i)printf("%d ",s[i]);//输出}else printf("Impossible");return 0;
}