萌新求助,这个贪心哪里有误
  • 板块CF125E MST Company
  • 楼主shight
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/3/16 21:06
  • 上次更新2023/11/5 01:58:55
查看原帖
萌新求助,这个贪心哪里有误
114859
shight楼主2021/3/16 21:06
#include<bits/stdc++.h>
#define N 1000001
using namespace std;
int n,m,k,cnt=0,to[N],val[N],nxt[N],head[N],id[N],dis[N],edge[N],vis[N],num=0,ans=0;
void add_edge(int x,int y,int z,int num)
{
	to[++cnt]=y;
	val[cnt]=z;
	nxt[cnt]=head[x];
	id[cnt]=num;
	head[x]=cnt;
}
struct Y
{
	int id,val;
	friend bool operator < (Y x,Y y)
	{
		return x.val>y.val;
	}
}; 
struct Li
{
	int dis,id,edge_id;
}dis_1[N];
priority_queue<Y> q;
vector<int> ans1;
int cmp(Li x,Li y)
{
	return x.dis<y.dis;
}
int main()
{
	scanf("%d %d %d",&n,&m,&k);
	if(n==1)
	{
		cout<<0<<endl;
		return 0;
	}
	if(k==0)
	{
		cout<<-1<<endl;
		return 0;
	}
	for(int i=1,x,y,z;i<=m;i++)
	{
		scanf("%d %d %d",&x,&y,&z);
		if(x!=1&&y!=1)
		{
			add_edge(x,y,z,i);
			add_edge(y,x,z,i); 
		}
		else
		{
			if(x!=1)swap(x,y);
			dis_1[++num].dis=z;
			dis_1[num].id=y;
			dis_1[num].edge_id=i;
		}
	}
	cout<<n-1<<endl;
	sort(dis_1+1,dis_1+num+1,cmp);
	memset(dis,0x3f3f3f3f,sizeof(dis));
	for(int nw=1;nw<=num;nw++)
		if(vis[dis_1[nw].id]==0)
		{
			ans+=dis_1[nw].dis;
			edge[dis_1[nw].id]=dis_1[nw].edge_id;
			dis[dis_1[nw].id]=0;q.push(Y{dis_1[nw].id,0});
			while(!q.empty())
			{
				int u=q.top().id;q.pop();
				if(vis[u]!=0)continue;
				vis[u]=1;ans+=dis[u];
				for(int i=head[u];i;i=nxt[i])
				{
					int v=to[i];
					if(dis[v]>val[i]&&vis[v]==0)
					{
						dis[v]=val[i];
						edge[v]=id[i];
						q.push(Y{v,dis[v]});
					}
				}
			}
			dis_1[nw].dis=2147483647;
			k--;
		}
	if(k<0)
	{
		cout<<-1<<endl;
		return 0;
	}
	for(int i=1;i<=num;i++)dis_1[i].dis=dis_1[i].dis-dis[dis_1[i].id];
	sort(dis_1+1,dis_1+num+1,cmp);
	for(int i=1;i<=k;i++)
	{
		edge[dis_1[i].id]=dis_1[i].edge_id;
		ans+=dis_1[i].dis;
	}
	//cout<<ans<<endl; 
	for(int i=2;i<=n;i++)
		printf("%d ",edge[i]);
}

具体思路是先把去掉根后的森林中的每棵树做最小生成树,再将1相连的每个点按照与1距离和最小生成树连接距离之差排序,取小的点,不知道为什么错了

2021/3/16 21:06
加载中...