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号
浙公网安备 33010602011771号