UESTC 889(UVA LA 6623) 水dfs
题意:给一个图,每个点有点权,每两个点最多有一条边相连,每个点至少和一个点通过边相连。要找出这样一个团,使得团内所有的点两两都有边相连且边不交叉,并且点权最大。
分析:因为是正宗的英语,所以当时读题目漏了一个条件---边不交叉,难度一下升级了,最终没能做出来。其实如果有这个条件,本来以为最多有三个点,再仔细结合样例分析一下的话就可以发现最多只有4个点,就可以dfs暴搜。
再多加一个点就会形成交叉。
1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #include<vector>
5 #define repu(i,a,b) for(int i=a;i<b;i++)
6 #define maxn 500
7 using namespace std;
8 int val[maxn],mp[maxn][maxn],n,ans;
9 int p[5];
10 bool vis[maxn];
11 int check(int num,int cur)///是否能和选好的点两两相连
12 {
13 repu(i,0,num)
14 {
15 if(!mp[p[i]][cur])
16 return 0;
17 }
18 return 1;
19 }
20 void dfs(int num,int cur,int sum)
21 {
22 ans = max(ans,sum);
23 if(num == 4) return;
24 repu(i,cur,n+1)
25 {
26 if(vis[i] || !check(num,i)) continue;
27 p[num] = i;
28 vis[i] = true;
29 dfs(num+1,i,sum+val[i]);
30 vis[i] = false;
31 }
32 }
33 int main()
34 {
35 int e,u,v;
36 while(~scanf("%d%d",&n,&e))
37 {
38 memset(mp,0,sizeof(mp));
39 repu(i,1,n+1)
40 scanf("%d",&val[i]);
41 repu(i,1,e+1)
42 {
43 scanf("%d%d",&u,&v);
44 mp[u][v] = mp[v][u] = 1;
45 }
46 ans = 0;
47 dfs(0,1,0);
48 printf("%d\n",ans);
49 }
50 return 0;
51 }
人生就像心电图,想要一帆风顺,除非game-over


浙公网安备 33010602011771号