您的位置:首页 > 其它

HDU 4313 Matrix

2016-09-14 23:43 344 查看
人一我百人十我万!!!

一开始想用最短路来求…结果发现节点好多。。。

发现是最小生成树里面的克鲁斯卡思想,加一些贪心就好了。

ac code:#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

#define si1(a) scanf("%d",&a)
#define si2(a,b) scanf("%d%d",&a,&b)
#define sd1(a) scanf("%lf",&a)
#define sd2(a,b) scanf("%lf%lf",&a,&b)
#define ss1(s) scanf("%s",s)
#define pi1(a) printf("%d\n",a)
#define pi2(a,b) printf("%d %d\n",a,b)
#define mset(a,b) memset(a,b,sizeof(a))
#define forb(i,a,b) for(int i=a;i<b;i++)
#define ford(i,a,b) for(int i=a;i<=b;i++)

typedef long long LL;
const int N=1100001;
const int M=6666666;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-7;
#define maxn 100005
__int64 sum;
int father[maxn];
bool vis[maxn];
struct p
{
int u,v,time;
}a[maxn];

bool cmp(p a,p b)
{
return a.time>b.time;
}

int find1(int u)
{
return u==father[u]?u:u=find1(father[u]);
}

void dfs(int x,int y,int z)
{
int u=find1(x);
int v=find1(y);
if(vis[u]&&vis[v])//必须删除的路
return ;
else
{
if(vis[u])
father[v]=u;
else
father[u]=v;
sum+=z;
}
}

int main()
{
int T;
si1(T);
while(T--)
{
int u,v;
__int64 ans=0;
sum=0;
si2(u,v);
ford(i,0,u)
father[i]=i;
mset(vis,0);
forb(i,0,u-1)
{
si2(a[i].u,a[i].v);
si1(a[i].time);
ans+=a[i].time;//总时
}
ford(i,1,v)
{
int cnt;
si1(cnt);
vis[cnt]=1;//记录节点是否有要删除的
}
sort(a,a+u-1,cmp);//贪心 从大到小排
forb(i,0,u-1)
dfs(a[i].u,a[i].v,a[i].time);
printf("%I64d\n",ans-sum);//做减法剩下的就是最小的
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: