关于差分约束
差分约束系统
1. Intervals
/*
Time: 1.31
Worker: Blank_space
Source: #10087. 「一本通 3.4 例 1」Intervals
建图 单源最长路
注意上下界的约束
*/
/*--------------------------------------------*/
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define emm(x) memset(x, 0x8f, sizeof x)
using namespace std;
/*--------------------------------------头文件*/
const int A = 1e4 + 7;
const int B = 1e5 + 7;
const int C = 1e6 + 7;
const int D = 1e7 + 7;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int FFF = 0x8fffffff;
/*------------------------------------常量定义*/
struct edge {int v, w;};
vector <edge> e[B];
int n, s = INF, t, dis[B];
queue <int> q;
bool vis[B];
/*------------------------------------变量定义*/
inline int read() {
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
/*----------------------------------------快读*/
int min(int x, int y) {return x < y ? x : y;}
int max(int x, int y) {return x > y ? x : y;}
/*----------------------------------------函数*/
int main()
{
n = read();
for(int i = 1; i <= n; i++)
{
int x = read() - 1, y = read(), z = read();
s = min(x, s); t = max(t, y);
e[x].push_back((edge){y, z});
}
for(int i = s; i <= t; i++) e[i].push_back((edge){i + 1, 0}), e[i + 1].push_back((edge){i, -1});
fill(dis + 1 + s, dis + 1 + t, -INF);
dis[s] = 0; q.push(s);
while(!q.empty())
{
int u = q.front(); q.pop(); vis[u] = 0;
for(int i = 0; i < e[u].size(); i++)
{
int v = e[u][i].v, w = e[u][i].w;
if(dis[v] < dis[u] + w)
{
dis[v] = dis[u] + w;
if(!vis[v]) {vis[v] = 1; q.push(v);}
}
}
}
printf("%d", dis[t]);
return 0;
}
2. 出纳员问题
/*
Time: 1.31
Worker: Blank_space
Source: #10088. 「一本通 3.4 例 2」出纳员问题
*/
/*--------------------------------------------*/
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define emm(x) memset(x, 0, sizeof x)
#define emmm(x) memset(x, 0x3f, sizeof x)
using namespace std;
/*--------------------------------------头文件*/
const int A = 1e4 + 7;
const int B = 1e5 + 7;
const int C = 1e6 + 7;
const int D = 1e7 + 7;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int FFF = 0x8fffffff;
/*------------------------------------常量定义*/
struct edge {int v, w;};
vector <edge> e[A];
int T, n, R[A], num[A], _c[A], c[A], dis[A], cnt, ans = INF;
bool vis[A], p;
/*------------------------------------变量定义*/
inline int read() {
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
/*----------------------------------------快读*/
bool check(int x)
{
emm(e); emmm(dis); emm(vis); cnt = 0; e[0].push_back((edge){24, x});
for(int i = 1 ; i <= 24 ; i++)
{
e[i].push_back((edge){i - 1, 0});
e[i - 1].push_back((edge){i, num[i]});
if(i > 8) e[i].push_back((edge){i - 8, -R[i]});
else e[i].push_back((edge){i + 16, x - R[i]});
}
queue <int> q;
q.push(0); dis[0] = 0;
while(!q.empty())
{
int u = q.front(); q.pop(); vis[u] = 0;
for(int i = 0; i < e[u].size(); i++)
{
int v = e[u][i].v, w = e[u][i].w;
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w; cnt++;
if(!vis[v]) {vis[v] = 1; q.push(v);}
if(cnt > 2000) return 0;
}
}
}
return dis[24] == x;
}
void work()
{
emm(R); emm(c); emm(num); ans = INF;
for(int i = 1; i <= 24; i++) R[i] = read();
n = read();
for(int i = 1; i <= n; i++) {int x = read() + 1; num[x]++;}
int l = 0, r = n;
while(l <= r)//二分最终人数
{
int mid = l + r >> 1;
if(check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
if(ans == INF) puts("No Solution");
else printf("%d\n", ans);
}
/*----------------------------------------函数*/
int main()
{
// freopen("Cashier.in", "r", stdin);
T = read();
while(T--) work();
return 0;
}
3. 糖果
/*
Time: 1.31
Worker: Blank_space
Source: #2436. 「SCOI2011」糖果
*/
/*--------------------------------------------*/
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define ll long long
#define emm(x) memset(x, 0, sizeof x)
#define emmm(x) memset(x, 0x8f, sizeof x)
using namespace std;
/*--------------------------------------头文件*/
const int A = 1e4 + 7;
const int B = 1e5 + 7;
const int C = 1e6 + 7;
const int D = 1e7 + 7;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int FFF = 0x8fffffff;
/*------------------------------------常量定义*/
struct edge {int v, w;};
vector <edge> e[B << 1];
int n, k, cnt, tot[B];
ll dis[B], ans;
bool vis[B];
/*------------------------------------变量定义*/
inline int read() {
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
/*----------------------------------------快读*/
/*----------------------------------------函数*/
int main()
{
n = read(); k = read();
for(int i = 1; i <= k; i++)
{
int x = read(), a = read(), b = read();
if(!(x & 1) && a == b) {puts("-1"); return 0;}
if(x == 1) e[b].push_back((edge){a, 0}), e[a].push_back((edge){b, 0});
if(x == 2) e[a].push_back((edge){b, 1});
if(x == 3) e[b].push_back((edge){a, 0});
if(x == 4) e[b].push_back((edge){a, 1});
if(x == 5) e[a].push_back((edge){b, 0});
}
for(int i = 1; i <= n; i++) e[0].push_back((edge){i, 1});
queue <int> q;
q.push(0); dis[0] = 0;
while(!q.empty())
{
int u = q.front(); q.pop(); vis[u] = 0;
if(tot[u] == n - 1) {puts("-1"); return 0;}
tot[u]++;
for(int i = 0; i < e[u].size(); i++)
{
int v = e[u][i].v, w = e[u][i].w;
if(dis[v] < dis[u] + w)
{
dis[v] = dis[u] + w;
if(!vis[v]) {vis[v] = 1; q.push(v);}
}
}
}
for(int i = 1; i <= n; i++) ans += dis[i];
printf("%lld", ans);
return 0;
}
4. 排队布局
/*
Time: 1.31
Worker: Blank_space
Source: #10090. 「一本通 3.4 练习 2」布局 Layout
直接分开写 spfa宽搜判环效率比较感人
开 long long
*/
/*--------------------------------------------*/
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
/*--------------------------------------头文件*/
const int A = 1e4 + 7;
const int B = 1e5 + 7;
const int C = 1e6 + 7;
const int D = 1e7 + 7;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int FFF = 0x8fffffff;
/*------------------------------------常量定义*/
struct edge {int v, w;};
vector <edge> e[1010];
int n, m1, m2, dis1[1010], vis1[1010];
ll dis2[1010];
bool vis2[1010], p;
/*------------------------------------变量定义*/
inline int read() {
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
return x * f;
}
/*----------------------------------------快读*/
void dfs(int u, int tp)
{
if(p) return ;
vis1[u] = tp;
for(int i = 0, lim = e[u].size(); i < lim; i++)
{
int v = e[u][i].v, w = e[u][i].w;
if(dis1[v] <= dis1[u] + w) continue;
dis1[v] = dis1[u] + w;
if(!vis1[v]) dfs(v, tp);
if(p) return ;
else if(vis1[v] == tp) {p = 1; return ;}
}
vis1[u] = 0;
}
/*----------------------------------------函数*/
int main()
{
n = read(); m1 = read(); m2 = read();
for(int i = 1; i <= m1; i++)
{
int x = read(), y = read(), z = read();
e[x].push_back((edge){y, z});
}
for(int i = 1; i <= m2; i++)
{
int x = read(), y = read(), z = read();
e[y].push_back((edge){x, -z});
}
for(int i = 2; i <= n; i++) e[i].push_back((edge){i - 1, 0});
for(int i = 1; i <= n; i++) {dfs(i, i); if(p) {puts("-1"); return 0;}}
for(int i = 1; i <= n; i++) e[0].push_back((edge){i, 0});
dfs(0, 0); if(p) {puts("-1"); return 0;}
for(int i = 1; i <= n; i++) dis2[i] = 1e13 + 7;
queue <int> q;
q.push(1); dis2[1] = 0;
while(!q.empty())
{
int u = q.front(); q.pop(); vis2[u] = 0;
for(int i = 0, lim = e[u].size(); i < lim; i++)
{
int v = e[u][i].v, w = e[u][i].w;
if(dis2[v] > dis2[u] + w)
{
dis2[v] = dis2[u] + w;
if(!vis2[v]) {vis2[v] = 1; q.push(v);}
}
}
}
if(dis2[n] == 1e13 + 7) puts("-2");
else printf("%lld", dis2[n]);
return 0;
}
——end

浙公网安备 33010602011771号