HDU 5006 Resistance(鞍山网络赛J题)

HDU 5006 Resistance

思路:这题由于数据是随机的。。电阻不是1就是0,就可以先缩点,把电阻为0的那些边缩掉,只考虑有电阻的边,这样的话缩下来点数就不多了,就可以利用高斯消元+基尔霍夫定律去搞了

代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 10005;
const int M = 40005;
const double eps = 1e-8;

int t, en;

struct Edge {
	int u, v;
	Edge(int u = 0, int v = 0) {
		this->u = u;
		this->v = v;
	}
} E[M];

int n, m, s, e, id[N], idx;
vector<int> g[N];
int parent[N];

int find(int x) {
	return x == parent[x] ? x : parent[x] = find(parent[x]);
}

void dfs(int u) {
	id[u] = idx;
	for (int i = 0; i < g[u].size(); i++) {
		int v = g[u][i];
		if (id[v] != -1) continue;
		dfs(v);
	}
}

double A[1005][1005];

void gauss(int n, int s, int e) {
	if (find(s) != find(e)) {
		printf("inf\n");
		return;
	}
	for (int i = 0; i < n; i++) {
		int r;
		for (r = i; r < n; r++)
			if (fabs(A[r][i]) >= eps)
				break;
		if (r == n) continue;
		for (int j = 0; j <= n; j++) swap(A[i][j], A[r][j]);
		for (int j = n; j > i; j--) A[i][j] /= A[i][i];
		A[i][i] = 1;
		for (int j = 0; j < n; j++) {
			if (i == j) continue;
			if (fabs(A[j][i]) >= eps) {
				for (int k = n; k > i; k--)
					A[j][k] -= A[j][i] * A[i][k];
				A[j][i] = 0;
			}
		}
	}
	printf("%.6lf\n", A[s][n] / A[s][s] - A[e][n] / A[e][e]);
}

int main() {
	scanf("%d", &t);
	while (t--) {
		memset(id, -1, sizeof(id));
		en = 0;
		scanf("%d%d%d%d", &n, &m, &s, &e);
		int u, v, r;
		for (int i = 0; i <= n; i++) {
			parent[i] = i;
			g[i].clear();
		}
		while (m--) {
			scanf("%d%d%d", &u, &v, &r);
			if (r == 0) {
				g[u].push_back(v);
				g[v].push_back(u);
			} else
				E[en++] = Edge(u, v);
		}
		idx = 0;
		for (int i = 1; i <= n; i++) {
			if (id[i] != -1) continue;
			dfs(i);
			idx++;
		}
		if (id[s] == id[e]) {
			printf("0.000000\n");
			continue;
		}
		memset(A, 0, sizeof(A));
		idx++;
		A[id[s]][idx] = 1;
		A[id[e]][idx] = -1;
		A[idx - 1][0] = 1;
		for (int i = 0; i < en; i++) {
			int u = id[E[i].u];
			int v = id[E[i].v];
			if (u == v) continue;
			int pu = find(u);
			int pv = find(v);
			if (pu != pv) parent[pu] = pv;
			A[u][u] += 1;
			A[v][v] += 1;
			A[u][v] -= 1;
			A[v][u] -= 1;
		}
		gauss(idx, id[s], id[e]);
	}
	return 0;
}
时间: 2024-11-09 03:03:36

HDU 5006 Resistance(鞍山网络赛J题)的相关文章

hdu 5446(2015长春网络赛J题 Lucas定理+中国剩余定理)

题意:M=p1*p2*...pk:求C(n,m)%M,pi小于10^5,n,m,M都是小于10^18. pi为质数 M不一定是质数 所以只能用Lucas定理求k次 C(n,m)%Pi最后会得到一个同余方程组x≡B[0](mod p[0])x≡B[1](mod p[1])x≡B[2](mod p[2])......解这个同余方程组 用中国剩余定理 Sample Input19 5 23 5 Sample Output6 1 # include <iostream> 2 # include <

西电校赛网络赛J题 lucas定理计算组合数

西电校赛网络赛J题  lucas定理计算组合数 问题 J: 找规律II 时间限制: 1 Sec  内存限制: 128 MB 提交: 96  解决: 16 [提交][状态][讨论版] 题目描述 现有数阵如下: 1    2  3   4     5    6 1   3   6  10  15 1   4  10   20 1   5   15 1    6 1 求这个数阵的第n行m列是多少(行列标号从1开始) 结果对10007取模 输入 多组数据,每组数据一行,包含两个整数n,m(1<=n<=

HDU5006 Resistance (2014年鞍山赛区网络赛J题)

1.题目描述:点击打开链接 2.解题思路:本题利用缩点+高斯消元解决.本题的最大特点就是电阻非零即一,如果电阻为0,说明零点之间是等电位点,可以看做一个整体,自然可以想到先利用并查集进行缩点操作,将复杂的电路图转化为不相等的电位点构成的电路图.如果转换完毕后,发现s和t在一个集合中,说明两点之间是等电位的,等效电阻为0,否则,对转换后的图G'重新判断连通性,依然可以利用并查集解决,如果发现不连通,说明s与t之间开路,电阻为inf,否则,就可以根据tot个点的电位列写方程. 我们令有1A的电流从点

HDU 5000 Clone(鞍山网络赛D题)

HDU 5000 Clone 这场就出了3题..就坑在这题上了,还好保住了名额 思路:要推出最大值的时候,每个人的属性和必然相同,并且这个和必然是所有和 / 2,这样的话,问题转化为给n个数字,要组合成sum / 2有多少种方法,就用dp背包推一遍就可以得解了. 现场的时候就没推出sum / 2就是答案 代码: #include <cstdio> #include <cstring> const int MOD = 1000000007; const int N = 2005; i

HDU 5001 Walk(鞍山网络赛E题)

HDU 5001 Walk 题目链接 思路:枚举每个要经过的点,然后进行状态转移,状态为dp[i][j],状态表示当前在j的点,已经走了i步,每次转移的时候,不从这个枚举的点出发,这样就可以求出所有路径经过该点的概率p, 然后1 - p就是不经过的答案 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; con

HDU 5003 Osu!(鞍山网络赛G题)

HDU 5003 Osu! 题目链接 就一签到题,排序之后for一遍计算出答案即可 代码: #include <cstdio> #include <cstring> #include <iostream> #include <string> #include <vector> #include <set> #include <map> #include <algorithm> #include <cmat

ZOJ 3818 Pretty Poem (2014年牡丹江赛区网络赛J题)

1.题目描述:点击打开链接 2.解题思路:本题是一道模拟题,输入一个串,要求判断是否形如"ABABA"或"ABABCAB".只需要对两种情况逐一尝试即可.然而这道题有诸多细节需要考虑.这里说一下我自己的方法. 首先,如果输入的串长度<5,那么直接输出No,或者去掉所有的标点后发现长度<5,输出No.长度上没问题后,写一个专门的solve(int type)函数,来判断是否是上述情况中的一种.对于第一种,只需要枚举A的长度即可,B的长度就是(len-3*i

HDU 6205 2017沈阳网络赛 思维题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6205 题意:给你n堆牌,原本每一堆的所有牌(a[i]张)默认向下,每次从第一堆开始,将固定个数的牌(b[i]张)翻上,然后下一堆继续,直到没有足够的牌翻上,然后你可以获得当前已经操作过的堆的所有牌.最初你可以调整堆的顺序,把第一堆放到最后一堆(逆时针旋转),你可以重复这个操作,问你要重复多少次这个操作,才能获得最多的牌. 解法:先把这个序列复制一遍放在原来的序列后面.当i=n的时候结束就可以了,每次

hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题

题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给定的学生成绩都异或上一次的答案 先将学生按每一门成绩都排一次序 这里将学生分块成sqrt(n)的块数,然后在当前块中用bitset容器来记录含有学生的状态 这里可以记录状态的前缀和,因为比后面成绩好的,必然比前面的学生的成绩也好 查询的时候只要查到正好比他高的学生属于哪一块,这样只要访问sqrt(n