Defense Tower | ||
Accepted : 89 | Submit : 172 | |
Time Limit : 3000 MS | Memory Limit : 65536 KB |
Defense TowerIn ICPCCamp, there are n cities and (n−1) (bidirectional) roads between cities. The i -th road is between the ai -th and bi -th cities. It is guaranteed that cities are connected. In the i -th city, there is a defense tower with power pi . The tower protects all cities with a road directly connected to city i . However, the tower in city i does not protect city i itself. Bobo would like to destroy all defense towers. When he tries to destroy the tower in city i , any not-destroyed tower protecting city i will deal damage whose value equals to its power to Bobo. Find out the minimum total damage Bobo will receive if he chooses the order to destroy the towers optimally. InputThe input contains at most 30 sets. For each set: The first line contains an integer n ( 1≤n≤105 ). The second line contains n integers p1,p2,…,pn ( 1≤pi≤104 ). The i -th of the last (n−1) lines contains 2 integers ai,bi ( 1≤ai,bi≤n ). OutputFor each set, an integer denotes the minimum total damage. Sample Input3 1 2 3 1 2 2 3 3 1 100 1 1 2 2 3 Sample Output3 2 |
原题链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1252
参考带博客:http://www.cnblogs.com/shuguangzw/p/5585781.html
思路:考虑每条边对玩家的伤害
假设连接的节点是u,v,破坏力是p[u]和p[v]
假设p[u]>p[v]
现在考虑u,v的删除顺序,如果先删u,这条边对玩家的伤害,是p[v],先删v,伤害是p[u]
所以显然对于每条边,我们都要先删权值大的,才能最好
怎么样才能对于每条边先删最大的呢,那就按照权值递减删就好了
所以 ret=Σ(min(p[u],p[v]))
复杂度O(n)
AC代码:
/**
* 行有余力,则来刷题!
* 博客链接:http://blog.csdn.net/hurmishine
*
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+10;
int a[maxn];
int main()
{
//freopen("data.txt","r",stdin);
int n;
while(cin>>n)
{
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
int ans=0;
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
ans+=min(a[x],a[y]);
}
cout<<ans<<endl;
}
return 0;
}
参考博客:http://blog.csdn.net/a852852852852/article/details/51720114
AC代码2:
/**
* 行有余力,则来刷题!
* 博客链接:http://blog.csdn.net/hurmishine
*
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
struct p
{
int num,val;
friend bool operator<(p a,p b)
{
return a.val<b.val;
}
}df[100005];
vector<int>edge[100005];
int main()
{
//freopen("data.txt","r",stdin);
int n,x,y,ans;
int vis[100005];
while(~scanf("%d",&n))
{
for(int i=0;i<=n;i++)
edge[i].clear();
priority_queue<p>q;
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
{
df[i].num=i;
scanf("%d",&df[i].val);
q.push(df[i]);
}
for(int i=1;i<=n-1;i++)
{
scanf("%d %d",&x,&y);
edge[x].push_back(y);
edge[y].push_back(x);
}
ans=0;
while(!q.empty())
{
int v=q.top().num;
q.pop();
for(int i=0;i<edge[v].size();i++)
{
if(vis[edge[v][i]]==0)
ans+=df[edge[v][i]].val;
}
vis[v]=1;
}
printf("%d\n",ans);
}
return 0;
}