首页 > 其他分享 >题解 NOD2207D【电报】

题解 NOD2207D【电报】

时间:2023-06-10 16:33:05浏览次数:59  
标签:NOD2207D int 题解 一行 cdots 电报 include 高斯消 deg

前置知识:高斯消元

已知 \(n\) 元线性一次方程组。关于 \(x_1,x_2,\cdots,x_n\)。

\[\begin{cases} a_{1, 1} x_1 + a_{1, 2} x_2 + \cdots + a_{1, n} x_n = b_1 \\ a_{2, 1} x_1 + a_{2, 2} x_2 + \cdots + a_{2, n} x_n = b_2 \\ \cdots \\ a_{n,1} x_1 + a_{n, 2} x_2 + \cdots + a_{n, n} x_n = b_n \end{cases} \]

求出它的唯一解。或者无解。或者无数解。

考虑写成一个类似矩阵的形式(假设 \(n=3\)):

\[\begin{bmatrix} a_{1,1} & a_{1,2} & a_{1,3} &|& b_1\\ a_{2,1} & a_{2,2} & a_{2,3} &|& b_2\\ a_{3,1} & a_{3,2} & a_{3,3} &|& b_3 \end{bmatrix}\]

对于这个矩阵我们可以有三种操作,而不改变它的任何信息:

  • 交换任意两行。
  • 对于一行的所有数字乘上同一个不为零的数。
  • 将某一行与另一行对应位置相加,放在另一行,前面的某一行不变。

我们可以用这三种操作解这个矩阵,如果有解。我们的做法是这样的:

  • 选一行的一个未知数。
  • 化其为一。
  • 用它消掉其他行的这个未知数,这样这个矩阵就只剩下它一个了。
  • 重复上述操作 \(n\) 次以至于每一行都形如 \(x_i=b'_i\)。

没有唯一解的情况,就是找完所有行发现有一个未知数完全没有了。

细分无解和无数解请见 https://www.luogu.com.cn/problem/solution/P2455 我不想再写了

problem

\(n\) 个点 \(m\) 条边的无向简单图。每条边应该有一个权值,你要用 \(1\) 到 \(m\) 的数字给它们赋权值,一个数字只能用一次。

一个人在图上,从 1 开始随机游走,每次等概率选择一条边走过去,花费代价是这条边的权值。

请合理地赋权值,使得这个人第一次走到 \(n\) 的期望代价最小。\(n\leq 500\)。

solution 1(\(n\leq 10\))

假设 \(E[i]\) 为从 \(i\) 第一次走到 \(n\) 的期望代价,可以写成一个关于其他 \(E[j]\) 和边权的多项式。

通过将 \(E[i]\) 当作未知数高斯消元,得到表示 \(E[1]\) 的关于所有边权的多项式。将这个多项式的系数从小到大排序,系数更小的赋予更大的权值,这样就能使 \(E[1]\) 最小。

solution 2

solution 1 的劣势在于边数太多了(\(O(n^2)\)),无法高斯消元。

考虑我们最后算出来那个系数是什么,实际上是那一条边的期望经过次数。而注意到 \((u,v)\) 边的经过次数显然等于 \(\frac{f_u}{deg_u}+\frac{f_v}{deg_v}\),其中 \(f_i\) 表示这个点的期望经过次数。

考虑计算 \(f_i\)。

  • \(f_n=0\)。
  • \(f_i=\sum_v\frac{f_v}{deg_v}\)
  • 注意 \(f_1\) 一上来就要经过一次,所以是 \(f_1=1+\sum_v\frac{f_v}{deg_v}\)

高斯消元上述内容即可。

code

点击查看代码
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cassert>
#include <algorithm>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stderr,##__VA_ARGS__)
#else
#define debug(...) void(0)
#endif
typedef long long LL;
const double eps=1e-7;
int n,m,deg[510],U[1<<18],V[1<<18];
vector<double> a[510];
void guass(){
	auto dec=[&](int i,int j,double d){for(int k=0;k<=n;k++) a[i][k]-=a[j][k]*d;};
	auto div=[&](int i,double d){for(int k=0;k<=n;k++) a[i][k]/=d;};
	for(int i=0;i<n;i++){
		int r=i; 
		for(int j=i+1;j<n;j++) if(fabs(a[j][i])>fabs(a[r][i])) r=j;
		if(fabs(a[r][i])<eps) assert(0);
		swap(a[i],a[r]);
		for(int j=0;j<n;j++) if(i!=j) dec(j,i,a[j][i]/a[i][i]);
	}
	for(int i=0;i<n;i++) div(i,a[i][i]);
}
int main(){
//	#ifdef LOCAL
//	 	freopen("input.in","r",stdin);
//	#endif
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%d%d",&U[i],&V[i]),deg[--U[i]]++,deg[--V[i]]++;
	for(int i=0;i<n;i++) a[i]=vector<double>(n+1),a[i][i]=-1;
	for(int i=1;i<=m;i++){
		auto add=[&](int u,int v){if(u!=n-1) a[u][v]+=1.0/deg[v];};
		add(U[i],V[i]),add(V[i],U[i]);
	}
	a[0][n]=-1,a[n-1][n-1]=1;
	guass();
	vector<double> w; w.reserve(m);
	for(int i=1;i<=m;i++) w.push_back(a[U[i]][n]/deg[U[i]]+a[V[i]][n]/deg[V[i]]);
	sort(w.begin(),w.end());
	double ans=0;
	for(int i=0;i<m;i++) ans+=w[i]*(m-i);
	printf("%.10lf\n",ans);
	return 0;
}

标签:NOD2207D,int,题解,一行,cdots,电报,include,高斯消,deg
From: https://www.cnblogs.com/caijianhong/p/solution-NOD2207D.html

相关文章

  • [SHOI2011]双倍回文 题解
    [SHOI2011]双倍回文题解看了一些写回文自动机的大佬的代码,我深感敬畏,于是我转身向Manacher走去现在荣登最优解第一页……说实话,这个方法的复杂度是很玄学的,但是加了一些优化之后,就几乎不可能被卡到\(O(n^2)\)了。具体思路如下:预处理字符串部分就略过吧我们预先跑一......
  • P7959 [COCI2014-2015#6] WTF 题解
    P7959[COCI2014-2015#6]WTF题解呃,是一道DP题说实话,原题实际上是不要输出一种方法的……但是似乎放这道题的人想增加一点难度?这里有两种做法,但都是DP。预备观察我们首先观察一些性质,以方便解题。循环不变:我们可以观察到,在\(n\)次变换后,序列会还原。也就是说,两个......
  • 题解 BZOJ4399 魔法少女LJJ
    前言XXX:你瞅你长得那个B样,俺老孙就(氧化钙)......这魔法(J8)少女能不能去死啊啊啊啊啊啊啊啊啊啊......正文"LJJ你是来搞笑的吧"你说得对,但是这数据就是骗人的.首先看题面:然后看样例:最后看数据范围:我惊奇的发现\(c\le7\)!家人们我真难绷qaq...问题分析显......
  • [AGC055B] ABC Supremacy 题解
    [AGC055B]ABCSupremacy题解题目描述给定两个长度为 \(n\) 的字符串 \(a\),\(b\)。你可以进行若干次以下操作:若 \(a\) 中的一个子串为 ABC,BCA 或 CAB,那么可以将这个子串替换为 ABC,BCA 或 CAB。求能否将 \(a\) 变成 \(b\),输出 YES 或 NO。解析不难发现,......
  • chrome 跨域问题解决
    1.后端设置了跨域,https下可以,http不可以高版本chrome配置了策略,如果访问私有网络,会出现禁止跨域chrome://flags/#block-insecure-private-network-requestsBlockinsecureprivatenetworkrequests.......
  • JAVA面试题解惑系列(六)——字符串(String)杂谈
    关键字:java面试题字符串string作者:臧圩人(zangweiren)网址:http://zangweiren.javaeye.com上一次我们已经一起回顾了面试题中常考的到底创建了几个String对象的相关知识,这一次我们以几个常见面试题为引子,来回顾一下String对象相关的其它一些方面。String的l......
  • quickfix协议当有中文时校验位错误问题解决
    quickfix校验位计算都是根据ISO-8859-1编码计算,知道这个规则后续我们处理中文就很好处理了。但是如果用ISO-8859-1编码有中文会出现乱码,如果将CharsetSupport.setCharset设置为UTF-8或者GBK时,在发送数据时会报java.nio.bufferoverflowexception:null,或者校验位失败。1、往step网......
  • JSOI2018 部分题解
    目录潜入行动防御网络列队潜入行动一眼直接DP。设\(f_{i,j,0/1,0/1}\)表示\(i\)子树内放了\(j\)个监听设备,\(i\)是否被子结点覆盖,\(i\)是否放了监听设备,\(i\)子树内除了\(i\)都被覆盖的方案数。转移是一个树形背包,时间复杂度\(\mathcal{O}(nk)\),只是常数有点大。......
  • Competitive Programmer 题解
    题目传送门一道模拟题。纯模拟肯定不行,考虑优化。\(60=2^2\times3\times5\),也就是说我们判断组合后的数字能否被\(2\),\(3\),\(10\)整除即可。如果这个数能被\(2\)整除,那么原数一定会存在偶数;如果这个数能被\(3\)整除,那么它的数字和应该也能被\(3\)整除;如果这个数......
  • CF547E Mike and Friends题解
    题目链接温馨提示:做本题之前可以先尝试这个:洛谷P2414阿狸的打字机(是简单版的uwu)。首先,这个题涉及多模式串匹配,首先想AC自动机。但是有个问题:我们如何去计算一个串出现的次数呢?我们先考虑查询一个串\(a\)在串\(b\)中出现的次数。首先,在AC自动机上有一个性质,就是如果......