游览计划 状压DP
【题目描述】
山山获得了长沙城内所有景点的门票各一张。然而,长沙城的交通并不发达,只有部分景点
之间有双向道路可供通行。一张门票只能被用一次,因而一个景点只能被经过一次。山山对
景点并不感兴趣,但是对路旁的花草却非常着迷。他希望从 1 号景点出发,走尽量长的路程,
在任意景点结束。你需要告诉他至多能走多长的路。
【输入格式】
第一行两个整数 n m
接下来 m 行,每行三个整数 s t w,表示从 s 号景点到 t 号景点有一条长为 w 的
双向道路。数据保证 s!=t,不保证同一对 s t 只出现一遍
【输出格式】
一行一个整数,表示最长路径长度
【样例输入】
3 3
1 2 1
2 3 2
1 3 4
【样例输出】
6
【数据范围】
100%的数据保证 1 ≤ n ≤ 10; 1 ≤ w ≤ 100
一开始用的dfs做这题,然后发现不好剪枝,然后就干脆写了状压DP。
其他的都写在注释里了。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define il inline
#define db double
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
il int gi()
{
int x=0,y=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
y=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*y;
}
int dist[145][145];
int f[100045][11];//dang qian zai j
int main()
{
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
int n=gi(),m=gi();
int top=(1<<n)-1;
int x,y,z;
for(int i=1;i<=m;i++)
{
x=gi(),y=gi(),z=gi();
dist[x][y]=max(dist[x][y],z);
dist[y][x]=max(dist[y][x],z);//mei ci qu zui da de jiu ke yi le
}
int ans=0;
for(int i=0;i<=top;i++)
{
if((i&1)==0)
continue;//bi xu cong 1 chu fa
for(int j=1;j<=n;j++)
if((i&(1<<(j-1)))==0)
{
int now=i+(1<<(j-1));//xia yi wei zhi
for(int k=1;k<=n;k++)//mei ju lai bian
if((i&(1<<(k-1)))!=0)//lai bian zou guo
if(dist[k][j]!=0)
f[now][j]=max(f[now][j],f[i][k]+dist[k][j]),ans=max(ans,f[now][j]);
}
}
printf("%d\n",ans);
return 0;
}
PEACE

浙公网安备 33010602011771号