P4138

差分约束

难度在读入

对于每一个限制,转化为两个不等式,用差分约束

每次询问相当于添加一个限制,问是否仍然存在合法的差分约束的解,直接重新跑差分约束即可

// Author: xiaruize
#ifndef ONLINE_JUDGE
bool start_of_memory_use;
#endif
#include <bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
clock_t start_clock = clock();
#endif
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
	if (a > b)
		return a;
	return b;
}
int min(int a, int b)
{
	if (a < b)
		return a;
	return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 50 + 10;

int n, m;
struct node
{
	vector<pii> vec;
	int cnt = 0;
} s[N];
vector<pii> f[N], g[N];
int dis[N];
bool vis[N];
int cnt[N];

void init()
{
	int kk;
	scanf("%lld\n", &kk);
	string str = "";
	string tmp;
	while (kk--)
	{
		getline(cin, tmp);
		str += tmp;
	}
	str += ' ';
	string ter = "";
	for (char c : str)
	{
		if (c == ' ' && (int)ter.size() == 5)
		{
			int x = ter[0] - 'A' + 1, nx = ter[1] - '0';
			int y = ter[3] - 'A' + 1, ny = ter[4] - '0';
			if (s[x].vec[nx].first > s[y].vec[ny].first || (s[x].vec[nx].first == s[y].vec[ny].first && s[x].vec[nx].second > s[y].vec[ny].second))
			{
				swap(x, y);
				swap(nx, ny);
			}
			f[y].push_back({x, s[y].vec[ny].second - s[x].vec[nx].first});
			f[x].push_back({y, -s[y].vec[ny].first + s[x].vec[nx].second});
			ter = "";
		}
		else if (isdigit(c) || isupper(c) || c == '-')
			ter += c;
	}
}

void check()
{
	queue<int> q;
	memset(dis, 0x3f, sizeof(dis));
	mms(vis, 0);
	mms(cnt, 0);
	q.push(0);
	dis[0] = 0;
	vis[0] = true;
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		vis[x] = false;
		for (auto [v, w] : g[x])
		{
			if (dis[v] > dis[x] + w)
			{
				dis[v] = dis[x] + w;
				cnt[v] = cnt[x] + 1;
				if (cnt[v] > n + 1)
				{
					printf("N");
					return;
				}
				if (!vis[v])
				{
					q.push(v);
					vis[v] = true;
				}
			}
		}
	}
	printf("Y");
}

void solve()
{
	scanf("%lld\n", &n);
	rep(i, 1, n)
	{
		f[0].push_back({i, 0});
		string str;
		getline(cin, str);
		str += ' ';
		int cur = 0, la = 0;
		rep(j, 0, str.size() - 1)
		{
			if (str[j] == ' ')
			{
				if (la)
				{
					s[i].cnt++;
					s[i].vec.push_back({la, cur - 1});
				} // cerr << la << ' ' << cur << endl;
				la = cur;
				cur = 0;
			}
			else if (isdigit(str[j]))
			{
				cur = cur * 10 + str[j] - '0';
			}
		}
	}
	init();
	int q;
	scanf("%lld\n", &q);
	while (q--)
	{
		string str;
		getline(cin, str);
		int x = str[0] - 'A' + 1;
		int y = str[3] - 'A' + 1;
		int nx = str[1] - '0';
		int ny = str[4] - '0';
		// cerr << x << ' ' << nx << ' ' << y << ' ' << ny << endl;
		// cerr << s[x].vec[nx].first << ' ' << s[x].vec[nx].second << endl;
		if (s[x].vec[nx].first > s[y].vec[ny].first || (s[x].vec[nx].first == s[y].vec[ny].first && s[x].vec[nx].second > s[y].vec[ny].second))
		{
			swap(x, y);
			swap(nx, ny);
		}
		int l = s[y].vec[ny].first - s[x].vec[nx].second, r = s[y].vec[ny].second - s[x].vec[nx].first;
		rep(i, 0, n)
		{
			g[i].clear();
			g[i] = f[i];
		}
		// cerr << l << ' ' << r << endl;
		g[y].push_back({x, r});
		g[x].push_back({y, -l});
		check();
	}
}

#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif

signed main()
{
	// freopen(".in","r",stdin);
	// freopen(".out","w",stdout);
	// ios::sync_with_stdio(false);
	// cin.tie(0);
	// cout.tie(0);
	int testcase = 1;
	// cin >> testcase;
	while (testcase--)
		solve();
#ifndef ONLINE_JUDGE
	cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl;
	cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl;
#endif
	return 0;
}
posted @ 2024-04-02 17:00  xiaruize  阅读(14)  评论(0)    收藏  举报