没有上司的舞会
没有上司的舞会
(题目已略)
表示这种题目唯一的坑点就是输入。。居然是多组数据!
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=6005;
class Graph{
public:
struct Edge{
int to, next; Graph *bel;
void set(int x, int y, Graph *g){
to=x; next=y; bel=g; }
inline int operator *(){ return to; }
Edge& operator ++(){
return *this=bel->edge[next]; }
};
void reset(){ //edge不用清零,因为最后跳到的结点是0
memset(fir, 0, sizeof(fir));
cntedge=0; edge[cntedge].to=0;
}
void addedge(int x, int y){
edge[++cntedge].set(y, fir[x], this);
fir[x]=cntedge;
}
Edge& getlink(int x){ return edge[fir[x]]; }
private:
int cntedge, fir[maxn];
Edge edge[maxn*2];
};
Graph g;
int n, root, hap[maxn], visit[maxn];
int f[maxn][2];
void dfs(int now, int par){
Graph::Edge e=g.getlink(now);
visit[now]=1; f[now][1]+=hap[now];
for (; *e; ++e){
if (*e==par) continue; dfs(*e, now);
f[now][0]+=max(f[*e][0], f[*e][1]);
f[now][1]+=f[*e][0];
}
}
//以后处理树的时候,注意怎么把森林连起来!不应该看入度出度!
int main(){
while (~scanf("%d", &n)){
g.reset(); memset(visit, 0, sizeof(visit));
memset(f, 0, sizeof(f));
for (int i=1; i<=n; ++i) scanf("%d", &hap[i]);
int x, y; scanf("%d%d", &x, &y);
while (x&&y){
g.addedge(x, y); g.addedge(y, x);
scanf("%d%d", &x, &y);
}
int ans=0;
for (int i=1; i<=n; ++i)
if (!visit[i]){
dfs(i, 0);
ans+=max(f[i][0], f[i][1]);
}
printf("%d\n", ans);
}
return 0;
}