记录编号 129792 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [HNOI 2010]城市建设 最终得分 100
用户昵称 GravatarChenyao2333 是否通过 通过
代码语言 C++ 运行时间 9.867 s
提交时间 2014-10-20 21:57:37 内存使用 1.27 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
const int MAXN=5e4+100;
struct ufs_{
	int fa[MAXN];
	void init(int n){ for(int i=0;i<=n;i++) fa[i]=i; }
	int get_fa(int n){
		if(fa[n]!=n) fa[n]=get_fa(fa[n]);
		return fa[n];
	}
	bool uni(int a,int b){
		int af=get_fa(a);
		int bf=get_fa(b);
		if(af==bf) return false;
		fa[af]=bf;
		return true;
	}
}ufs;

struct edge{
	int u,v;
	int cost;
	int id;
	bool rem,uni;
	edge(){ u=v=cost=id=0; uni=rem=false;}
	bool operator < (const edge & e)const{
		return cost<e.cost;
	}
};

struct query{
	int id;
	int cost;
}querys[MAXN];

int N,M,Q;
LL Ans[MAXN];
vector<edge> ES;

void init(){
	scanf("%d %d %d",&N,&M,&Q);
	for(int i=1;i<=M;i++){
		edge e; scanf("%d %d %d",&e.u,&e.v,&e.cost);
		e.id=i;
		ES.push_back(e);
	}
	for(int i=1;i<=Q;i++){
		query & q=querys[i];
		scanf("%d %d",&q.id,&q.cost);
	}
}

bool isinset(int n,set<int> & s){
	return s.find(n)!=s.end();
}

void solve(int left,int right,vector<edge> E,int n,LL sum,int upd_left,int upd_right){
	
	//把之前的更新给更新了 
	map<int,int> e2q; 
	if(left==right) upd_right=right;
	for(int i=0;i<E.size();i++)
		e2q.insert(make_pair(E[i].id,i));
	for(int i=upd_left;i<=upd_right;i++){
		query & q=querys[i];
		if(e2q.find(q.id)!=e2q.end()){
			int p=e2q[q.id];
			E[p].cost=q.cost;
		}
	}


	sort(E.begin(),E.end());
	
	//暴力 
	if(left==right){
		ufs.init(n+10);
		for(int i=0;i<E.size();i++){
			edge & e=E[i];
			if(ufs.uni(e.u,e.v)) sum+=e.cost;
		}
		Ans[left]=sum;
		return;
	}
	
	//es里面存的是left,right之间操作的边...
	set<int> es;
	for(int i=left;i<=right;i++)
		es.insert(querys[i].id);
	
	//扔边 
	ufs.init(n+10);
	for(int i=0;i<E.size();i++){
		edge & e=E[i];
		if(isinset(e.id,es)) continue;
		if(ufs.uni(e.u,e.v)==false)
			e.rem=true;
	}
	
	//缩点 
	ufs.init(n+10);
	for(int i=0;i<E.size();i++){
		edge & e=E[i];
		if(isinset(e.id,es)) ufs.uni(e.u,e.v);
	}
	for(int i=0;i<E.size();i++){
		edge & e=E[i];
		if(isinset(e.id,es) || e.rem)continue;
		if(ufs.uni(e.u,e.v)) e.uni=true,sum+=e.cost;
	}
	
	//重建 
	ufs.init(n+10);
	for(int i=0;i<E.size();i++){
		if(E[i].uni) ufs.uni(E[i].u,E[i].v);
	}
	map<int,int> m;int tn=0;
	for(int i=1;i<=n;i++){
		int fa=ufs.get_fa(i);
		if(fa==i) m[i]=++tn;
	}
	vector<edge> new_e;
	for(int i=0;i<E.size();i++){
		edge e=E[i];
		if(e.rem || e.uni) continue;
		e.u=m[ufs.get_fa(e.u)]; e.v=m[ufs.get_fa(e.v)];
		new_e.push_back(e);
	}
	
	int mid=(left+right)/2;
	solve(left,mid,new_e,tn,sum,left,0);
	solve(mid+1,right,new_e,tn,sum,left,mid);
}

int main(){
	freopen("hnoi2010_city.in","r",stdin);
	freopen("hnoi2010_city.out","w",stdout);
	init();
	solve(1,Q,ES,N,0,1,0);
	for(int i=1;i<=Q;i++)
		printf("%lld\n",Ans[i]);
	return 0;
}