游览计划 状压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