• CF125E MST Company


    换句话说就是要求一号点的出度为k的最短路

    容易发现:当连在1号节点的几个边同时加一个数的时候,1号店的度会减少,反之,当同时增大一个k的时候,1号点的度会增大

    因此,我们考虑二分一个数作为连在1号节点的那几条边修改的数值,进行二分查找出答案即可

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <vector>
    #define maxn 5500
    #define maxm 1100000
    #define rep(x,y,z) for(int x = y ; x <= z ; x ++)
    using namespace std ;
    int n , m , kk ;
    struct dy{
    	int u , v , w , id ;
    	int operator < (const dy &x) const {
    		return w == x.w ? u < x.u : w < x.w ;
    	}
    }a[maxm] ;
    vector<int>ans ;
    int fa[maxn] ;
    int find(int x) {
    	return x == fa[x] ? x : fa[x] = find(fa[x]) ;
    }
    void unionn(int x ,int y){
    	fa[find(x)] = find(y) ;
    }
    int read() ;
    int ksm(int k) {
    	ans.clear() ;
    	rep(i,1,n) fa[i] = i ;
    	int cnt = 0 , in = 0 ;
    	rep(i,1,m) {
    		if(a[i].u == 1 || a[i].v == 1) {
    			a[i].w += k ;
    		}
    	}sort(a+1,a+1+m) ;
    	rep(i,1,m) {
    		int u = a[i].u , v = a[i].v , w = a[i].w ;
    		int fu = find(u) , fv = find(v) ;
    		if(fu == fv) continue ; 
    		fa[fv] = fu ;
    		if(u == 1 || v == 1) in ++  ;
    		ans.push_back(a[i].id) ;
    		cnt ++ ;
    		if(cnt == n-1) break ;
    	}
    	rep(i,1,m) {
    		if(a[i].u == 1 || a[i].v == 1) a[i].w -= k ;
    	}return in ;
    	
    }
    int deal(int k) {
    	ans.clear() ;
    	rep(i,1,n) fa[i] = i ;
    	int cnt = 0 , in = 0 ;
    	rep(i,1,m) {
    		if(a[i].u == 1 || a[i].v == 1) {
    			a[i].w += k ;
    		}
    	}sort(a+1,a+1+m) ;
    	rep(i,1,m) {
    		int u = a[i].u , v = a[i].v , w = a[i].w ;
    		int fu = find(u) , fv = find(v) ;
    		if(fu == fv) continue ;
    		if(a[i].u == 1 && in == kk) continue ;
    		fa[fv] = fu ;
    		if(u == 1 || v == 1) in ++ ;
    		cnt ++ ;
    		ans.push_back(a[i].id) ;
    	}
    	rep(i,1,m) {
    		if(a[i].u == 1 || a[i].v == 1) a[i].w -= k ;
    	}
    	if(cnt != n-1 || in != kk) {
    		puts("-1") ;
    		exit(0) ;
    	} 
    	cout << n-1 << endl ;
    	for(int i = 0 ; i < ans.size() ; i ++) cout << ans[i] << " " ;
    	puts("") ;exit(0) ;
    	return in ; 
    }
    int main () {
    	n = read() , m = read() , kk = read() ;
    	rep(i,1,m) {
    		a[i].u = read() , a[i].v = read() , a[i].w = read() , a[i].id = i ;
    		if(a[i].u > a[i].v) swap(a[i].u,a[i].v) ;
    	}int l = -1e5 , r = 1e5 , Ans = -1e9 ;
    	while(l <= r) {
    		int mid = (l+r) / 2 ;
    		if(ksm(mid) < kk) r = mid - 1 ;
    		else {
    			l = mid + 1 , Ans = mid ; 
    		}
    	}
    	deal(Ans) ;
    	return 0 ;
    }
    int read() {
    	int x = 0 , f = 1 ; char s = getchar() ;
    	while(s > '9' || s < '0') {if(s == '-') f = -1 ; s = getchar() ;}
    	while(s <='9' && s >='0') {x = x * 10 + (s-'0'); s = getchar() ;}
    	return x*f ;
    }
    
  • 相关阅读:
    Java 枚举 封装 错误代码
    java for android sqlite数据的操作:说实话,我用了ADO.NET的思想,自己封装了DataTable,DataRow,DataAdapter
    flash在影片剪辑里面跳转场景
    java的byte与C#的异同引起的字符处理问题。
    Microsoft.ReportViewer winform web 部署问题
    MSN退休,寻找微软如何融合MSN的答案:体验skype6国际版MSN功能。
    昨天晚上修改违章查询的算法,坐等下个月的查询量了。
    发现了X64平台的IIS 中 ASP.net还是存在X86与X64不兼容的情况
    百度UEditor使用详解
    Struts防止表单重复提交(转载)
  • 原文地址:https://www.cnblogs.com/lyt020321/p/11635437.html
Copyright © 2020-2023  润新知