ACdream 1135(MST-最小生成树边上2个值,维护第一个最小的前提下让另一个最小)

F - MST

Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)

SubmitStatus

Problem Description

Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices together.  A single graph can have many different spanning trees. We can also assign a weight to each edge, which is a number representing
how unfavorable it is, and use this to assign a weight to a spanning tree by computing the sum of the weights of the edges in that spanning tree. A minimum spanning tree (MST) is then a spanning tree with weight less than or equal to the weight of every other
spanning tree.

------ From wikipedia

Now we make the problem more complex. We assign each edge two kinds of weight: length and cost. We call a spanning tree with sum of length less than or equal to others MST. And we want to find a MST who has minimal sum of cost.

Input

There are multiple test cases.

The first line contains two integers N and M indicating the number of vertices and edges in the gragh.

The next M lines, each line contains three integers a, b, l and c indicating there are an edge with l length and c cost between a and b.

1 <= N <= 10,000

1 <= M <= 100,000

1 <= a, b <= N

1 <= l, c <= 10,000

Output

For each test case output two integers indicating the sum of length and cost of corresponding MST.

If you can find the corresponding MST, please output "-1 -1".

Sample Input

4 5
1 2 1 1
2 3 1 1
3 4 1 1
1 3 1 2
2 4 1 3

Sample Output

3 3

图中边有2个值l,c,求关于l的MST,在此基础上求min∑c

直接把边按l从小到大(第一关键字),c从小到大(第二关键字)排序,然后用Kruskal算法

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define MAXN (1000+10)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int n;
char a[MAXN][MAXN];
ll p10[MAXN]={0};
ll pow2(ll b)
{
   if (b==1) return 10;
   if (b==0) return 1;
   if (p10[b]) return p10[b];
   ll p=pow2(b/2)%F;
   p=(p*p)%F;
   if (b&1)
   {
       p=(p*10)%F;
   }
   p10[b]=p;
   return p;
}
ll pow2(ll a,ll b)
{
	if (b==1) return a;
	if (b==0) return 1;
	ll p=pow2(a,b/2)%F;
	p=p*p%F;
	if (b&1)
	{
		p=(p*a)%F;
	}
	return p;
}
ll tot[MAXN]={0};
ll mulinv(ll a)
{
	return pow2(a,F-2);
}
int main()
{
//	freopen("sum.in","r",stdin);
//	freopen("sum.out","w",stdout);
	scanf("%d",&n);
	For(i,n)
	{
		scanf("%s",a[i]+1);

	}
	/*
	For(i,n)
	{
		For(j,n) cout<<a[i][j];
		cout<<endl;
	}
	*/
	For(i,n)
	{
		For(j,n) tot[i]+=a[i][j]-'0'+a[j][i]-'0';
	}

//	For(i,n) cout<<tot[i]<<endl;

//	cout<<mul(pow2(10,1232),mulinv(pow2(10,1232)))<<endl;
//	cout<<mulinv(9);

	ll c9=mulinv(9);

	For(i,n) p10[i]=pow2(i);

	ll ans=0;
	For(i,n)
	{
		ll t=sub(p10[n-i+1],1),a=tot[i];
		t=mul(t,c9);
		t=mul(a,t);
		ans=add(ans,mul(t,i));
	}
	cout<<ans<<endl;

	return 0;
}

ACdream 1135(MST-最小生成树边上2个值,维护第一个最小的前提下让另一个最小)

时间: 2024-08-10 23:29:37

ACdream 1135(MST-最小生成树边上2个值,维护第一个最小的前提下让另一个最小)的相关文章

ACdream 1135 MST

MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Problem Description Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices together.  A single

POJ1258 Agri-Net MST最小生成树题解

搭建一个最小代价的网络,最原始的最小生成树的应用. 这里使用Union find和Kruskal算法求解. 注意: 1 给出的数据是原始的矩阵图,可是须要转化为边表示的图,方便运用Kruskal,由于须要sort 2 降低边.一个矩阵最多须要(N*N-N)>>1条边,有人讨论本题是否有向,那是无意义的.由于本题的最小生成树和方向无关. 3 使用Union find是为了推断是否有环.比原始推断快非常多. #include <stdio.h> #include <stdlib.

【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)

[BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的M行,每行三个整数Ui,Vi,Wi,表示顶点Ui与Vi之间有一条边,其权值为Wi.所有的边在输入中会且仅会出现一次.再接着N-1行,每行两个整数Xi.Yi,表示顶点Xi与Yi之间的边是T的一条边. Output 输出最小权值 Sample Input 6 9 1 2 2 1 3 2 2 3 3 3

[BZOJ1937][SHOI2004]Mst最小生成树(KM算法,最大费用流)

1937: [Shoi2004]Mst 最小生成树 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 802  Solved: 344[Submit][Status][Discuss] Description Input 第 一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的M行,每行三个整数Ui,Vi,Wi,表示顶点Ui与Vi之间有一条边,其权值为 Wi.所有的边在输入中会且仅会出现一次.再接着N-1

Python List remove()方法-用于移除列表中某个值的第一个匹配项

描述 remove() 函数用于移除列表中某个值的第一个匹配项. 语法 remove()方法语法: list.remove(obj) 参数 obj -- 列表中要移除的对象. 返回值 该方法没有返回值但是会移除两种中的某个值的第一个匹配项. 实例 以下实例展示了 remove()函数的使用方法: #!/usr/bin/python aList = [123, 'xyz', 'zara', 'abc', 'xyz']; aList.remove('xyz'); print "List : &quo

一维差值维护心得

一维差值维护是一种简单的小算法,该算法用一个巧妙地数列机制解决了多次对数列进行数据加减操作的复杂度,这个算法的思维偏向于动态规范.下面我们从一个问题开始入手介绍这个算法: 问题描述: 已知n个数的数列a,有m次操作,每次操作给定l,r,k三个数,使得al到ar内所有数加上k.注意l到r的区间包含al和ar两个数. 输入数据: 第一行n和m,接下来一行有n个数,表示数列a,接下来有m行,每行有三个数l,r,k,详细解释参考问题描述. 输出数据: 1行n个数,表示经过m次操作之后的数组a. 输入样例

不修改模板的前提下修改VisualState中的某些值

UWP里有一件非常令人不爽的事,大部分控件只提供了Normal状态下的Background,Foreground,BorderBrush,而控件一般至少具有Normal.PointerOver.Pressed.Disabled,ItemContainerStyle还有Selected.PointerOverSelected.PressedSelected这几种.那么常规方法怎么修改这几个状态内的值呢? 当然是贴一遍又臭又长的Style. 那如果有很多不是很一样的控件,除了修改模板或者自定义一个控

【KM】BZOJ1937 [Shoi2004]Mst 最小生成树

这道题拖了好久因为懒,结果1A了,惊讶∑( 口 || [题目大意] 给定一张n个顶点m条边的有权无向图.现要修改各边边权,使得给出n-1条边是这张图的最小生成树,代价为变化量的绝对值.求最小代价之和. [思路] 思路有点神,并不是我这种蒟蒻能够想到的XD 显然由贪心,树边必定变成wi-di,非树边必定变成wi+di (di≥0) 为了满足Mst的性质,考察一条非树边j,它加最小生成树后,必定构成一个环.对于环上的每一条树边i,有wi-di≤wj+dj,即di+dj≥wi-wj.这非常类似于KM的

UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)

题意:要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方的权(注意不需要开方的),这说明每两个点都可以使其互通.接着又q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需要做的就是连上还未通的即可,q<=8.可以多买.求最小生成树所需的代价. 思路:与普通求MST不同的就是多了套餐,而且还可以多买.每个套餐有买或不买两种可能,那么有28种可能,即256种. 如果不买套餐,至少需要求1次MST是确定的,这个复杂度已经是O(n*n)了.还得考虑哪些餐套可以搭