差分约束 刷题记录

把问题转化成一堆不等式,然后用最短路求解

POJ3169 Layout

最后要求1和n之间最大dis是多少  ->  转化为得到一堆  d[n] - d[1] <= xi  然后求xi的最小值

对于给出的是d[u] - d[v] >= xi  同乘-1转化为 d[v] - d[u] <= -xi 即可

然后用spfa求 1到n的最短路

若有负环则无解,若求得的最短路为inf则说明1,n间距离可随便大

代码:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <queue>
 4 #define nmax 50010
 5 #define f(c,a,b) for(int c=a; c<=b; c++)
 6
 7 using namespace std;
 8 typedef long long ll;
 9 struct edge{
10     int v, ne, w;
11 }e[nmax];
12 int cnt=0, n, x, y;
13 int head[nmax]={0}, c[nmax]={0}, inq[nmax]={0};
14 ll d[nmax]={0};
15 const ll inf = 1e15;
16
17 void addedge(int u, int v, int w){
18     cnt++;
19     e[cnt].v = v;
20     e[cnt].w = w;
21     e[cnt].ne = head[u];
22     head[u] = cnt;
23 }
24
25 void build(){
26     scanf("%d%d%d", &n, &x, &y);
27     int u, v, w;
28     f(i, 1, x){
29         scanf("%d%d%d", &u, &v, &w);
30         addedge(u, v, w);
31     }
32     f(i, 1, y){
33         scanf("%d%d%d", &u, &v, &w);
34         addedge(v, u, -w);
35     }
36     f(i, 2, n) d[i] = inf;
37 }
38
39 bool spfa(){
40     queue <int> q;
41     q.push(1);
42     inq[1] = c[1] = 1;
43     while(!q.empty()){
44         int u = q.front();
45         if( c[u] > n ) return false;
46         q.pop();
47         inq[u] = 0;
48         for (int i=head[u]; i; i=e[i].ne){
49             int v = e[i].v;
50             if(d[v] > d[u] + e[i].w){
51                 d[v] = d[u] + e[i].w;
52                 if(inq[v]) continue;
53                 inq[v] = 1;
54                 c[v]++;
55                 q.push(v);
56             }
57         }
58     }
59     return true;
60 }
61
62 int main(){
63     build();
64     if( spfa() ){
65         if(d[n]==inf) printf("-2\n");
66         else printf("%lld\n", d[n]);
67     }else{
68         printf("-1\n");
69     }
70     return 0;
71 }

??

原文地址:https://www.cnblogs.com/jiecaoer/p/12236066.html

时间: 2024-11-09 01:31:30

差分约束 刷题记录的相关文章

BZOJ 刷题记录 PART 4

[BZOJ1143]CTSC的题目...先用floyed传递闭包,然后直接上匈牙利算法. [BZOJ1452]从未写过的二维树状数组.好像很简单.. struct two_bit { int f[305][305]; inline void add(int x,int z,int A) { for (;x<=n;x+=L(x)) for (int y=z;y<=m;y+=L(y)) f[x][y]+=A; } inline int ask(int x,int z) { int ans=0; f

POJ 1364 King --差分约束第一题

题意:求给定的一组不等式是否有解,不等式要么是:SUM(Xi) (a<=i<=b) > k (1) 要么是 SUM(Xi) (a<=i<=b) < k (2) 分析:典型差分约束题,变换,令Ti = SUM(Xj) (0<=j<=i).  则表达式(1)可以看做T(a+b)-T(a-1) > k,也就是T(a-1)-T(a+b) < -k,又因为全是整数,所以T(a-1)-T(a+b) <= -k-1.  同理,(2)看做T(a+b)-T(

[2015.6.28] OI刷题记录

FZSZOJ刷题记录: 1051 砝码称重: DP 多重背包 1058 liqeuer: 序列DP 1061 挖地雷:DP,注意需要倒过来做DP,同时记录路径. 1059 Number:DP 1054 数塔问题:同数字三角形,普通DP 1390 等式问题:爆搜,枚举每个+号或-号的位置 1006 中位数:维护大根堆+小根堆,每次插入调整 1005 Cube Stacking:并查集维护当前在第几个和当前集合的高度,并查集变种. 1073 DNA分子的最佳比对:序列DP 1110 奖学金:傻逼题,

首师大附中科创教育平台 我的刷题记录(3)

首师大附中科创教育平台我的刷题记录(给大家刷11--15题吧) 仅供同学们参考,禁止抄袭!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #include<iostream> #include<math.h> using namespace std; int main() { int x,y; cin>>x; y=abs(x+2); cout<<x*x-y+5<<endl; return 0; } 绝对值函数 #include

BZOJ 刷题记录 PART 5

拖了好久才写的. [BZOJ2821]接触分块大法.这道题略有点新颖.首先我们先分块,然后统计每块中每个数出现的个数. 下面是联立各个方块,预处理出第I个方块到第J个方块出现正偶数次数的个数. for (i=1;i<=s;i++) { for (j=i;j<=s;j++) { sum[i][j]=sum[i][j-1]; for (k=a[j].l;k<=a[j].r;k++) { temp[data[k]]++; if (!(temp[data[k]]&1)) sum[i][j

首师大附中科创教育平台 我的刷题记录(7)

首师大附中科创教育平台我的刷题记录(这次给大家刷多一点,31--40题吧) 仅供同学们参考,禁止抄袭!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #include<iostream> using namespace std; int main() { int n; cin>>n; if(n%4==0&&n%100!=0||n%400==0) cout<<"yes"<<endl; else cout&

首师大附中科创教育平台 我的刷题记录(6)

首师大附中科创教育平台我的刷题记录(给大家刷26--30题吧) 仅供同学们参考,禁止抄袭!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #include<iostream> #include<math.h> using namespace std; int main() { double I,R,r,E; cin>>I>>R>>r; E=I*(R+r); cout<<E<<endl; return 0

首师大附中科创教育平台 我的刷题记录 0284 最强大脑

从现在开始,我的刷题记录都开始给大家一个一个刷!今天给大家献上“E”级题:最强大脑!! 试题编号:0284     最强大脑 难度级别:E: 运行时间限制:3000ms: 运行空间限制:256000KB: 代码长度限制:2000000B 试题描述 zhb国是一个传说中的国度,国家的居民叫做最强(chang)大脑(diao).Zhb国是一个N×M的矩形方阵,每个格子代表一个街区.然而zhb国是没有交通工具的.居民大脑(diao)们完全靠地面的弹射装置来移动.每个街区都装有弹射装置.使用弹射装置是需

首师大附中科创教育平台 我的刷题记录(5)

首师大附中科创教育平台我的刷题记录(给大家刷21--25题吧) 仅供同学们参考,禁止抄袭!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #include<iostream> #include<math.h> using namespace std; int main() { double a,b,x; cin>>a>>b; x=-b/a; cout<<x<<endl; return 0; } 一元一次方程 #in