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;
}

浙公网安备 33010602011771号