[Wc2007]剪刀石头布 迭代

本文介绍了一种高效算法,用于在一个给定边集的图中,通过自行安排剩余边来最大化三元环的数量。算法首先计算可能的三元环总数,然后通过调整节点的出度来优化配置,确保所有节点的度数尽可能均匀,从而增加三元环的数量。该算法优于传统的费用流方法,实现上更简洁快速。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description
给你若干条边,你自己安排剩下的边,求最多有多少个三元环。


Sample Input
3
0 1 2
0 0 2
2 2 0


Sample Output
1
0 1 0
0 0 1
1 0 0


首先可能的三元环数量为:C(n,3)C(n,3)C(n,3)
考虑一个非法的三元环就相当于有一个点有两个出度,那么答案就是:
ans=C(n,3)−∑i=1nC(degi,2)ans=C(n,3)-\sum_{i=1}^nC(degi,2)ans=C(n,3)i=1nC(degi,2)
这个东西你是可以直接费用流的吗。
但是Discuss又有一种做法,我去了解了一下:
就是你先给他们随机安排一个值,然后你期望让所有人的degdegdeg尽量相近,就相当于让一些人的degdegdeg变小,一些人的degdegdeg变大,Discuss是说只要找到当前的degdegdeg差距大于等于222,就直接修改。正确性不会证,比较显然???时间复杂度,我的姿势不好可能会很慢,其实一次增广路可以做到O(m)O(m)O(m),复杂度应该是O(m2)O(m^2)O(m2)的。
我这个算法比我写的费用流快很多。。。


#include <ctime>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;
typedef long long LL;
int _max(int x, int y) {return x > y ? x : y;}
int _min(int x, int y) {return x < y ? x : y;}
const int N = 101;
int read() {
	int s = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
	return s * f;
}
void put(int x) {
	if(x >= 10) put(x / 10);
	putchar(x % 10 + '0');
}

struct node {
	int x, y;
} b[N * N]; int cnt;
struct edge {
	int x, y, next;
} e[N * N * 2]; int len, last[N];
int ans, a[N][N], id[N * N];
int tt, v[N];
int du[N];

void ins(int x, int y) {
	e[++len].x = x, e[len].y = y;
	e[len].next = last[x], last[x] = len;
}

bool cmp(int x, int y) {return du[x] > du[y];}

bool findrd(int x, int d) {
	v[x] = tt;
	for(int k = last[x]; k; k = e[k].next) {
		int y = e[k].y;
		if(v[y] != tt && a[x][y]) {
			if(d - du[y] >= 2) {
				a[x][y] = 0, a[y][x] = 1;
				ans -= du[y], du[y]++;
				return 1;
			} else if(findrd(y, d)){
				a[x][y] = 0, a[y][x] = 1;
				return 1;
			}
		}
	} return 0;
}

int main() {
	srand(200815147);
	int n = read();
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= n; j++) {
			a[i][j] = read();
			if(i <= j) continue;
			if(a[i][j] == 0) ++du[j];
			else if(a[i][j] == 1) ++du[i];
			else {
				ins(i, j), ins(j, i);
				b[++cnt].x = i, b[cnt].y = j;
			}
		}
	} 
	for(int i = 1; i <= cnt; i++) id[i] = i;
	random_shuffle(id + 1, id + cnt + 1);
	for(int i = 1; i <= cnt; i++) {
		int hh = id[i];
		if(du[b[hh].x] <= du[b[hh].y]) ++du[b[hh].x], a[b[hh].x][b[hh].y] = 1, a[b[hh].y][b[hh].x] = 0;
		else ++du[b[hh].y], a[b[hh].x][b[hh].y] = 0, a[b[hh].y][b[hh].x] = 1;
	} 
	ans = n * (n - 1) / 2 * (n - 2) / 3;
	for(int i = 1; i <= n; i++) ans -= du[i] * (du[i] - 1) / 2;
	bool bk = 1;
	while(bk) {
		bk = 0;
		for(int i = 1; i <= n; i++) id[i] = i;
		sort(id + 1, id + n + 1, cmp);
		for(int i = 1; i <= n; i++) {
			tt++; int x = id[i];
			if(findrd(x, du[x])) {
				du[x]--, ans += du[x];
				bk = 1; break;
			}
		}
	} put(ans), puts("");
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= n; j++) put(a[i][j]), putchar(' ');
		puts("");
	}
	return 0;
}

资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 “STC单片机电压测量”是一个以STC系列单片机为基础的电压检测应用案例,它涵盖了硬件电路设计、软件编程以及数据处理等核心知识点。STC单片机凭借其低功耗、高性价比和丰富的I/O接口,在电子工程领域得到了广泛应用。 STC是Specialized Technology Corporation的缩写,该公司的单片机基于8051内核,具备内部振荡器、高速运算能力、ISP(在系统编程)和IAP(在应用编程)功能,非常适合用于各种嵌入式控制系统。 在源代码方面,“浅雪”风格的代码通常简洁易懂,非常适合初学者学习。其中,“main.c”文件是程序的入口,包含了电压测量的核心逻辑;“STARTUP.A51”是启动代码,负责初始化单片机的硬件环境;“电压测量_uvopt.bak”和“电压测量_uvproj.bak”可能是Keil编译器的配置文件备份,用于设置编译选项和项目配置。 对于3S锂电池电压测量,3S锂电池由三节锂离子电池串联而成,标称电压为11.1V。测量时需要考虑电池的串联特性,通过分压电路将高电压转换为单片机可接受的范围,并实时监控,防止过充或过放,以确保电池的安全和寿命。 在电压测量电路设计中,“电压测量.lnp”文件可能包含电路局信息,而“.hex”文件是编译后的机器码,用于烧录到单片机中。电路中通常会使用ADC(模拟数字转换器)将模拟电压信号转换为数字信号供单片机处理。 在软件编程方面,“StringData.h”文件可能包含程序中使用的字符串常量和数据结构定义。处理电压数据时,可能涉及浮点数运算,需要了解STC单片机对浮点数的支持情况,以及如何高效地存储和显示电压值。 用户界面方面,“电压测量.uvgui.kidd”可能是用户界面的配置文件,用于显示测量结果。在嵌入式系统中,用
资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 在 Android 开发中,Fragment 是界面的一个模块化组件,可用于在 Activity 中灵活地添加、删除或替换。将 ListView 集成到 Fragment 中,能够实现数据的动态加载与列表形式展示,对于构建复杂且交互丰富的界面非常有帮助。本文将详细介绍如何在 Fragment 中使用 ListView。 首先,需要在 Fragment 的局文件中添加 ListView 的 XML 定义。一个基本的 ListView 元素代码如下: 接着,创建适配器来填充 ListView 的数据。通常会使用 BaseAdapter 的子类,如 ArrayAdapter 或自定义适配器。例如,创建一个简单的 MyListAdapter,继承自 ArrayAdapter,并在构造函数中传入数据集: 在 Fragment 的 onCreateView 或 onActivityCreated 方法中,实例化 ListView 和适配器,并将适配器设置到 ListView 上: 为了提升用户体验,可以为 ListView 设置点击事件监听器: 性能优化也是关键。设置 ListView 的 android:cacheColorHint 属性可提升滚动流畅度。在 getView 方法中复用 convertView,可减少视图创建,提升性能。对于复杂需求,如异步加载数据,可使用 LoaderManager 和 CursorLoader,这能更好地管理数据加载,避免内存泄漏,支持数据变更时自动刷新。 总结来说,Fragment 中的 ListView 使用涉及局设计、适配器创建与定制、数据绑定及事件监听。掌握这些步骤,可构建功能强大的应用。实际开发中,还需优化 ListView 性能,确保应用流畅运
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值