和上一题一样,建议去CF的GYM里交。
题意:找一个团(里面任意两点都有直接的路径连接)使得团内点的权值加起来最大。
方法:一开始想的超复杂,没敢做。后来经大神指点,图为平面图,任意两路径不相交,这样,团的点的个数最大就是4。接下来就简单了,搜吧。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
vector<int>g[500];
bool p[500][500];
int a[500];
int n,m;
void init()
{
for(int i=1;i<=n;i++)g[i].clear();
memset(p,0,sizeof(p));
}
int main()
{
int u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
p[u][v]=p[v][u]=1;
if(u>v)swap(u,v);
g[u].push_back(v);
}
int ans=0;
for(int i=1;i<=n;i++)
{
int size=g[i].size();
for(int j=0;j<size;j++)
{
ans=max(ans,a[i]+a[g[i][j]]);
for(int k=j+1;k<size;k++)
{
if(!p[g[i][j]][g[i][k]])continue;
ans=max(ans,a[i]+a[g[i][j]]+a[g[i][k]]);
for(int h=k+1;h<size;h++)
{
if(!p[g[i][h]][g[i][k]]||!p[g[i][h]][g[i][j]])continue;
ans=max(ans,a[i]+a[g[i][j]]+a[g[i][k]]+a[g[i][h]]);
}
}
}
}
printf("%d\n",ans);
}
return 0;
}