CF - 776D 2-SAT

题意:

n个门,每个门有一个初始的状态,或开或锁,有m个开关,每个开关都能控制若干门的状态,题目保证每个门一定会受到两个开关的影响。问是否有可能让所有门都开。

思路:

2-SAT,对于开关来考虑,每个开关要么开要么关,两种状态true和false,设xi为true就是开关i打开,xi为false就是开关i关闭,对每个门来说,如果一开始就是打开,那么变化量就要为0,若这个门受到开关i和j的控制,那么i和j只有两种可能,要么xi==true&&yi==true,要么xi==false&&yi==false,转化成2-SAT的格式来说就是(xi || !yi) && (!xi || yi),同理,初始状态关闭的也可以这么考虑,最后直接套个板。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 1e5 + 10;

struct TwoSAT {
	int n;
	vector <int> G[MAXN * 2];
	bool mark[MAXN * 2];
	int S[MAXN * 2], c;

	 bool dfs(int x) {
	 	if (mark[x ^ 1]) return false;
	 	if (mark[x]) return true;
	 	mark[x] = true;
	 	S[c++] = x;
	 	for (int i = 0; i < G[x].size(); i++)
	 		if (!dfs(G[x][i])) return false;
	 	return true;
	 }

	 void init(int n) {
	 	this -> n = n;
	 	for (int i = 0; i < n * 2; i++) G[i].clear();
	 	memset(mark, 0, sizeof(mark));
	 }

	 void add_clause(int x, int xval, int y, int yval) {
	 	x = x * 2 + xval;
	 	y = y * 2 + yval;
	 	G[x ^ 1].push_back(y);
	 	G[y ^ 1].push_back(x);
	 }

	 bool solve() {
	 	for (int i = 0; i < n * 2; i += 2) {
	 		if (!mark[i] && !mark[i + 1]) {
	 			c = 0;
	 			if (!dfs(i)) {
	 				while (c > 0) mark[S[--c]] = false;
	 				if (!dfs(i + 1)) return false;
	 			}
	 		}
	 	}
	 	return true;
	 }
} twoSAT;

int sta[MAXN];
vector <int> swt[MAXN];

int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &sta[i]);
	}
	for (int i = 1; i <= m; i++) {
		int num, x;
		scanf("%d", &num);
		for (int j = 1; j <= num; j++) {
			scanf("%d", &x);
			swt[x].push_back(i - 1);
		}
	}
	twoSAT.init(m);
	for (int i = 1; i <= n; i++) {
		int x = swt[i][0], y = swt[i][1];
		if (sta[i] == 1) {
			twoSAT.add_clause(x, 1, y, 0);
			twoSAT.add_clause(x, 0, y, 1);
		}
		else {
			twoSAT.add_clause(x, 1, y, 1);
			twoSAT.add_clause(x, 0, y, 0);
		}
	}
	if (twoSAT.solve()) puts("YES");
	else puts("NO");
	return 0;
}

``` import os import matplotlib.ticker as mticker import netCDF4 as nc import matplotlib.path as mpath import cmaps import matplotlib.pyplot as plt import numpy as np import matplotlib as mpl import cartopy.crs as ccrs import cartopy.feature as cfeature from netCDF4 import Dataset from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER import regionmask import cartopy.io.shapereader as shpreader #-------------------------------- 1. 读取NC文件 --------------------------------# nc_file = r"D:\biyelunwen\data\sat_swe_flow.nc" ds = Dataset(nc_file) lon = ds.variables['longitude'][:] lat = ds.variables['latitude'][:] data1 = ds.variables['flow_sat_to_swe'][:] # 三维数组(time, lat, lon) data2 = ds.variables['flow_swe_to_sat'][:] # 生成示例数据:取第一个时间步 dss = np.array([data1[0], data2[0]]) # $\boxed{数据索引修正}$ #-------------------------------- 2. 图形参数设置 --------------------------------# mpl.rcParams.update({ "font.family": 'Arial', "mathtext.fontset": 'cm', "font.size": 12, "axes.linewidth": 1 }) proj = ccrs.NorthPolarStereo(central_longitude=0) img_extent = [-180, 180, 20, 90] #-------------------------------- 3. 创建画布 --------------------------------# fig = plt.figure(figsize=(14,6), dpi=200) title_list = ['(a) inf from SAT to SWE', '(b) inf from SWE to SAT'] # 定义统一色标 vmin, vmax = -4, 4 levels = np.linspace(vmin, vmax, 21) #-------------------------------- 4. 主绘图循环 --------------------------------# for j in range(2): # 创建子图并调整位置 left = 0.05 + j * 0.45 # $\boxed{布局优化}$ ax = fig.add_axes([left, 0.1, 0.4, 0.8], projection=proj) # 设置标题 ax.set_title(title_list[j], fontsize=14, pad=20) # 添加地理要素 ax.set_extent(img_extent, ccrs.PlateCarree()) ax.add_feature(cfeature.COASTLINE.with_scale('50m'), lw=0.5) ax.add_feature(cfeature.LAND, facecolor='lightgray') # 绘制网格线 gl = ax.gridlines(draw_labels=True, linestyle='--', color='grey') gl.xlocator = mticker.FixedLocator([-180, -90, 0, 90, 180]) gl.ylocator = mticker.FixedLocator(np.arange(20, 91, 10)) gl.ylabel_style = {'size': 10} gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER # 创建二维网格 lon2d, lat2d = np.meshgrid(lon, lat) # $\boxed{坐标网格生成}$ # 绘制填色图 cf = ax.contourf(lon2d, lat2d, dss[j], levels=levels, cmap='RdBu_r', transform=ccrs.PlateCarree(), extend='both') # 添加青藏高原边界 tp_shp = shpreader.Reader(r"D:\biyelunwen\TPBoundary_new(2021)\TPBoundary_new(2021).shp") ax.add_geometries(tp_shp.geometries(), crs=ccrs.PlateCarree(), edgecolor='red', facecolor='none', linewidth=1.5, linestyle='--') # 裁剪圆形边界 theta = np.linspace(0, 2*np.pi, 100) verts = np.vstack([np.sin(theta), np.cos(theta)]).T circle = mpath.Path(verts * 0.5 + [0.5, 0.5]) ax.set_boundary(circle, transform=ax.transAxes) #-------------------------------- 5. 添加颜色条 --------------------------------# cax = fig.add_axes([0.25, 0.05, 0.5, 0.03]) # 调整位置 cbar = fig.colorbar(mpl.cm.ScalarMappable( norm=mpl.colors.Normalize(vmin, vmax), cmap='RdBu_r'), cax=cax, orientation='horizontal', extend='both') cbar.set_label('Information Flow Strength (×10⁻³)') plt.show()```TypeError: Input z must be 2D, not 1D
最新发布
03-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值