【USACO】 洞穴奶牛

题目描述

贝西喜欢去洞穴探险。这次她去的地方由 N 个洞穴组成,编号分别是 1 到 N,1 号洞穴是出发
的起点。
洞穴之间由 M 条隧道相连,双向通行,第 i 条隧道连接 A i 和 B i 。每条隧道有个尺寸,第 i 条
隧道的尺寸为 W i ,如果贝西的身材超过了隧道的尺寸,就钻不过去了。贝西的身材可用一个数字来
描述,一开始是 0。
前期准备时,贝西已在 K 个里洞穴存放了食物,她当然不会放过它们。当她吃掉一份食物后,
身材就会增加 1。在探险的过程中,她想吃掉尽量多的食物,但要保证最后能返回起点。请帮她计划
一下,什么样的路线才能吃到最多的食物?
注意,探险的路线可以重复,所以路过有食物时,可以留到下次路过的时候再吃。

输入

• 第一行:三个整数 N,M 和 K,1 ≤ N ≤ 100,1 ≤ M ≤ 1000,1 ≤ K ≤ 14
• 第二行到第 K+1 行:第 i+1 行有一个整数 C i ,表示在第 C i 号洞穴里有一份食物,1 ≤ C i ≤ N
• 第 K +2 行到第 K +M +1 行:第 i+K +1 行有三个整数 A i ,B i 和 W i ,1 ≤ A i ,B i ≤ N,1 ≤
W i ≤ 100

输出

• 单个整数:表示贝西最多能吃几份食物

样例输入

6 7 5 1 2 3 4 5 1 2 3 3 6 2 6 2 10 2 4 1 5 1 1 4 5 1 1 6 1

样例输出

4

提示

先吃 5 号洞里的,再吃 3,2,最后走回 1,

 

吃掉 1 里的最后一份食物
 
 
题解:
K<=14 很明显可以状压 ,然后发现想不出什么方程式,于是就上状压搜索,分析复杂度(1<<K)*N = 10^6 随便水过.
于是上记忆搜乱搞 F[i][j] 到i这个点状态为j 是否走过
注意:如果有食物在1号点,注意特判
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int N=105,M=1005,Z=14;
 8 int gi(){
 9     int str=0;char ch=getchar();
10     while(ch>'9' || ch<'0')ch=getchar();
11     while(ch>='0' && ch<='9')str=str*10+ch-48,ch=getchar();
12     return str;
13 }
14 int n,m,k,w[N],head[N],num=1,id[N];
15 struct Lin{
16     int next,to,dis;
17 }a[M<<1];
18 void init(int x,int y,int z){
19     a[++num].next=head[x];
20     a[num].to=y;
21     a[num].dis=z;
22     head[x]=num;
23 }
24 bool mark[N][1<<Z];int ans=0;
25 void dfs(int x,int p,int tot)
26 {
27     if(mark[x][p])return ;
28     mark[x][p]=true;
29     if(x==1 && tot>=ans)
30     {
31         if(w[1] &&  !(p&(1<<(id[1]-1))))ans=tot+1;
32         else ans=tot;
33     }
34     int u;
35     for(int i=head[x];i;i=a[i].next)
36     {
37         u=a[i].to;
38         if(tot>a[i].dis)continue;
39         dfs(u,p,tot);
40         if(p&(1<<(id[x]-1)))continue;
41         if(w[x] && tot<a[i].dis)dfs(u,p|(1<<(id[x]-1)),tot+1);
42     }
43 }
44 int main()
45 {
46     int x,y,z;
47     n=gi();m=gi();k=gi();
48     for(int i=1;i<=k;i++)x=gi(),w[x]=1,id[x]=i;
49     for(int i=1;i<=m;i++)
50     {
51         x=gi();y=gi();z=gi();
52         init(x,y,z);init(y,x,z);
53     }
54     dfs(1,0,0);
55     printf("%d",ans);
56     return 0;
57 }

 

posted @ 2017-06-22 12:26  PIPIBoss  阅读(351)  评论(0编辑  收藏  举报