萌新90分求助 WA#10
查看原帖
萌新90分求助 WA#10
308384
Morpheuse楼主2021/9/26 20:32

代码已经被改的不成样子了

kru + 倍增做法

错误信息:第1行第7个 读到3 期待4

On line 1 column 7, read 3, expected 4

#include<bits/stdc++.h>
#define LL long long
using namespace std;

const LL maxn = 800010;
const LL maxm = 8000100;
const LL inf = 2147483647999999999;

LL n,m;
LL g1,g2,g3,c,total;
LL ans = inf;

struct node
{
	LL from,to,data,next;
}e[maxm],g[maxm * 2],l[maxm];
LL head1[maxn],head2[maxn];
LL sum1 = 0 , sum2 = 0;//1 2 分别表示读进的边 生成用的边
LL vism[maxn];

inline void add(LL x , LL y , LL z , node *e , LL *head , LL &sum)
{
	e[++sum].from = x;
	e[sum].to = y;
	e[sum].data = z;
	e[sum].next = head[x];
	head[x] = sum;
}


inline bool cmp(node x , node y)
{
	return x.data < y.data;
}

LL fa[maxn];
int find(int x)
{
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void init()
{
	for(LL i = 1 ; i <= n ; ++ i)
		fa[i] = i;
}

LL f[maxn][40],w[maxn][40];
LL de[maxn];
void dfs(LL now , LL fat)
{
	de[now] = de[fat] + 1;
	f[now][0] = fat;
	for(LL i = 1 ; i <= 24 ; ++ i)
	{
		f[now][i] = f[f[now][i - 1]][i - 1];
		w[now][i] = max(w[now][i - 1] , w[f[now][i - 1]][i - 1]);
	}
	for(LL i = head2[now] ; i ; i = g[i].next)
	{
		if(g[i].to != fat)
		{
	//		cout<<g[i].to<<"的0级祖先:"<<g[i].data<<endl;
			w[g[i].to][0] = g[i].data;
			dfs(g[i].to , now);
		}
			
	}
}
LL lca(LL x , LL y , LL data)
{
//	cout<<"本次不能使用"<<data<<endl;
	LL total = 0;
	if(de[x] < de[y])
		swap(x , y);
	for(LL i = 24 ; i >= 0 ; -- i)
	{
		if(de[f[x][i]] >= de[y])
		{
			if(w[x][i] != data)
				total = max(total , w[x][i]);
			if(w[x][i] != data)
				total = max(total , w[y][i]);
	//		cout<<"跳到"<<x<<"的"<<i<<"级祖先:"<<w[x][i]<<"total:"<<total<<endl;
			x = f[x][i];
			
		}
	}
//	cout<<"现在都调到了"<<x<<" "<<y<<"最大是"<<total<<endl;
	if(x == y)
	{
		if(w[x][0] != data)
			total = max(total , w[x][0]);
		if(w[y][0] != data)
			total = max(total , w[y][0]);
		return total;
	}
		
	for(LL i = 22 ; i >= 0 ; -- i)
	{
		if(f[x][i] != f[y][i])
		{
			if(w[x][i] != data)
				total = max(total , w[x][i]);
			if(w[x][i] != data)
				total = max(total , w[y][i]);
			x = f[x][i] , y = f[y][i];
			
		}
	}
	if(w[x][0] != data)
		total = max(total , w[x][0]);
	if(w[y][0] != data)
		total = max(total , w[y][0]);
	//cout<<"最后尝试了"<<w[x][0]<<','<<w[y][0]<<"L:"<<total<<endl;
	return total;
}
int main()
{
	scanf("%d%d", &n,&m);
	for(LL i = 1 ; i <= m ; ++ i)
	{
		scanf("%d%d%d", &g1,&g2,&g3);
		add(g1 , g2 , g3 , e , head1 , sum1);
	}
	init();
	sort(e + 1 , e + 1 + m , cmp);
	total = 0;
	for(LL i = 1 ; c < n && i <= m ; ++ i)
	{
		LL fx = find(e[i].from) , fy = find(e[i].to);
		if(fx != fy)
		{
			fa[fx] = fy;
			total += e[i].data;
		//	cout<<e[i].from<<","<<e[i].to<<"now"<<total<<endl;
			add(e[i].from , e[i].to , e[i].data , g , head2 , sum2);
			add(e[i].to , e[i].from , e[i].data , g , head2 , sum2);
			vism[i] = 1; 
			++ c;
		}
	}
/*	cout<<"生成树结果:"<<total<<endl; 
	for(LL i = 1 ; i <= 2* n - 2 ; ++ i)
	{
		prLLf("%d-%d:%d\n", g[i].from,g[i].to,g[i].data);
	}*/
	dfs(1 , 0);
	//遍历所有最小的边尝试替换并记录替换结果 
	for(LL i = 1 ; i <= m ; ++ i)
	{
		if(vism[i] == 0)
		{
		//	cout<<"尝试加边:"<<e[i].from<<"-"<<e[i].to<<":"<<e[i].data<<",找到区间内最大:"<<endl;
			LL best = lca(e[i].from , e[i].to , e[i].data);
		//	cout<<"best"<<best<<endl;
			if(e[i].data - best != 0)
				ans = min(ans , e[i].data - best);
		//	cout<<"现在最优解"<<ans<<endl;
		}
	/*	else
		{
			cout<<e[i].from<<' '<<e[i].to<<":"<<e[i].data<<"用过了"<<endl;
		}*/
	}
	cout<<total + ans;
	return 0;
}

/*
6 6
1 2 2
2 3 2
3 6 1
1 4 1
4 5 1
3 4 2
*/
2021/9/26 20:32
加载中...