首页 > 其他分享 >【XSY2416】带权图(图论,高斯消元)

【XSY2416】带权图(图论,高斯消元)

时间:2022-10-30 10:24:45浏览次数:49  
标签:方程 ch ll 带权 inline XSY2416 高斯消 mod

感觉非常高妙。

考虑暴力做法。

首先对于题目中的第三种限制:若两个环满足,那么这两个环拼起来得到的环肯定也满足。

那么我们可以只考虑那些互相独立的简单环。

随便找到原图的一棵生成树,那么一条非树边可以对应一个简单环,共 \(m-(n-1)\) 个,看成 \(m-(n-1)\) 条方程。

再配上第二条限制,总共就得到了 \(n+m-(n-1)=m+1\) 条方程,共有 \(m\) 个未知数。

\(O(m^3)\) 高斯消元即可得到 60pts。

考虑先利用一些方程消去一些东西降低未知数个数。

设 \(path_u=v_0=1,v_1,\cdots,v_k=u\) 为任意一条从 \(1\) 到 \(u\) 的路径,记 \(x_u=\sum\limits_{i=0}^{k-1}B(v_i,v_{i+1})C(v_i,v_{i+1})-A(v_i,v_{i+1})\)。

利用第三条限制,可以证明无论 \(path_u\) 如何取,\(x_u\) 总是相同的。

那么对于任意一条边 \((u,v)\),就有:

\[C(u,v)=\dfrac{x_v-x_u+A(u,v)}{B(u,v)} \]

于是任意的 \(C(u,v)\) 都被表示成只和 \(x\) 有关的量。

\(x\) 的数量是 \(n\) 个,\(x_1=0\) 加上第二条限制共有 \(n+1\) 条方程,高斯消元即可,时间复杂度 \(O(n^3)\)。

看起来很妙,理性分析一下我们是如何利用部分方程减少未知数个数的:

仍然考虑一开始的生成树做法,随便选一个点作为根,设 \(x_u\) 表示树上从根到 \(u\) 的简单路径经过的边的 \(BC-A\) 的和。那么对于树上的边 \((u,v)\) 我们就知道 \(C(u,v)\) 用 \(x\) 表示的表达式。

对于一条非树边 \((u,v)\),暴力做法中它贡献了一条方程,根据这条方程我们可以推导出 \(C(u,v)=\dfrac{x_v-x_u+A(u,v)}{B(u,v)}\)。

使用了 \(m-(n-1)\) 条方程,消掉了 \(m-(n-1)\) 个未知数,很合理。

反正这个表示方法还是很妙的。

#include<bits/stdc++.h>

#define N 110
#define M 2010
#define ll long long

using namespace std;

namespace modular
{
	ll mod;
	inline ll add(ll x,ll y){return x+y>=mod?x+y-mod:x+y;}
	inline ll dec(ll x,ll y){return x-y<0?x-y+mod:x-y;}
	inline ll mul(ll x,ll y){return (__int128)x*(__int128)y%mod;}
	inline void Add(ll &x,ll y){x=x+y>=mod?x+y-mod:x+y;}
	inline void Dec(ll &x,ll y){x=x-y<0?x-y+mod:x-y;}
	inline void Mul(ll &x,ll y){x=(__int128)x*(__int128)y%mod;}
}using namespace modular;

inline ll poww(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=mul(ans,a);
		a=mul(a,a);
		b>>=1;
	}
	return ans;
}

inline ll read()
{
	ll x=0;
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^'0');
		ch=getchar();
	}
	return x*f;
}

struct Edge
{
	int u,v;
	ll a,b;
}e[M];

int n,m;
ll a[N][N],x[N];

void add(int u,int v,ll A,ll B)
{
	if(u==n) return;
	ll invB=poww(B,mod-2);
	Dec(a[u][u],invB);
	if(v!=n) Add(a[u][v],invB);
	Dec(a[u][n],mul(A,invB));
}

void Gauss(int n)
{
	for(int i=1;i<=n;i++)
	{
		int p=i;
		for(int j=i+1;j<=n;j++)
			if(a[j][i]) p=j;
		swap(a[i],a[p]);
		ll inv=poww(a[i][i],mod-2);
		for(int j=i+1;j<=n;j++)
		{
			ll tmp=mul(a[j][i],inv);
			for(int k=i;k<=n+1;k++)
				Dec(a[j][k],mul(a[i][k],tmp));
		}
	}
	for(int i=n;i>=1;i--)
	{
		for(int j=i+1;j<=n;j++)
			Dec(a[i][n+1],mul(a[i][j],x[j]));
		x[i]=mul(a[i][n+1],poww(a[i][i],mod-2));
	}
}

int main()
{
//	freopen("graph3.in","r",stdin);
//	freopen("graph3.out","w",stdout);
	n=read(),m=read(),mod=read();
	for(int i=1;i<=m;i++)
	{
		e[i].u=read(),e[i].v=read(),e[i].a=read(),e[i].b=read();
		add(e[i].u,e[i].v,e[i].a,e[i].b);
		add(e[i].v,e[i].u,dec(0,e[i].a),e[i].b);
	}
	Gauss(n-1);
	for(int i=1;i<=m;i++)
	{
		ll c=add(dec(x[e[i].v],x[e[i].u]),e[i].a);
		Mul(c,poww(e[i].b,mod-2));
		printf("%lld\n",c);
	}
	return 0;
}

标签:方程,ch,ll,带权,inline,XSY2416,高斯消,mod
From: https://www.cnblogs.com/ez-lcw/p/16840593.html

相关文章

  • 高斯消元
    高斯消元是求解线性方程组的方法。对于一个\(m\)个等式\(n\)个未知数的方程组,我们可以将其写成\(m\times(n+1)\)的增广矩阵的形式:对于这个矩阵我们可以进行三......
  • luogu P3232 [HNOI2013]游走 (期望, 高斯消元)
    https://www.luogu.com.cn/problem/P3232思路:算出每条边的期望访问次数,将期望访问次数多的赋予小的编号。一条边的期望访问次数=访问点u的期望/u的度+访问点v的期望......
  • CF963E Circles of Waiting(高斯消元,主元法)
    CF963ECirclesofWaiting平面直角坐标系上有一个点,开始在\((0,0)\),每秒钟这个点都会随机移动:如果它在\((x,y)\),下一秒它去\(4\)个方向的概率为\(p_0,p_1,p_2,......
  • 高斯消元
    盘活一下线性代数。我也不知道为什么看着格路计数然后看到LGV引理然后就来补线性代数了。高斯消元可以拿来干什么?解方程组。线性方程组。怎么解?我们现在有一个线性方程组......
  • Luogu P3389【模板】高斯消元法
    题意给定一个线性方程组,对其求解。$1\leqn\leq100,\left|a_i\right|\leq{10}^4,\left|b\right|\leq{10}^4$题解因为之前贺题解的时候没有理解高斯-约......
  • 异或方程组高斯消元模板
    inlinevoidsolve(intn){for(inti=1,top=1;i<=n;i++,top++){intcur=0;for(intj=top;j<=n;j++)if(m......
  • [补档]高斯消元做题记录/或曰 学习笔记
    早就退役啦!乍一看挺水的。P2455[SDOI2006]线性方程组板子题。codeP4035[JSOI2008]球形空间产生器给定一个\(n\)维的球体上\(n+1\)个点的坐标\(a_{i,j}\)。求......
  • 高斯消元详解
    高斯消元一,什么是高斯消元?用来解决需要解方程组的题目时所用的一种算法。适用于以下该种形式的式子:\[\begin{cases}a_1=k_{1,1}*x_{1,1}+k_{1,2}*x_{1,2}+\cdots+k_{1......
  • 实例92 高斯消去法
    #include<stdio.h>#include<stdlib.h>#include<malloc.h>#include<math.h>intGS(int,double**,double*,double);double**TwoArrayAlloc(int,int);voidTwo......
  • 高斯消去
    importjava.util.Scanner;publicclassGaoSi{/***列主元高斯消去法*/staticdoubleA[][];staticdoubleb[];staticdoublex[];sta......