原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-SoundHound-Inc-Programming-Contest-2018-E.html

题目传送门 - AtCoder SoundHound Inc. Programming Contest 2018 E

题意

  给定一个无向连通图,有 $n$ 个节点 $m$ 条带权边,第 $i$ 条边连接 $x_i,y_i$ ,权值为 $s_i$ ,没有重边、自环。

  现在,请你给每一个节点取一个正整数点权。问有多少种方案使得任意一条边两端的节点权值和等于边权。

  $2\leq n\leq 100000,1\leq m\leq 100000$

  所有输入的数字都在 $10^9$ 以内。

题解

  先吐槽:

    这题细节好坑啊!!!我当场做到只 WA 一个点,没想到 20 分钟还是没有发现特判,然后 GG 。然后考完发现在我没注意的地方忘记特判了??然后考完不到10分钟把它过了。就加了几行。

  然后讲做法。

  设 $v_i$ 为第 $i$ 个点的点权。

  首先,我们考虑到对于所有的 $i$ ,有 $v_{x_i}+v_{y_i}=s_i$ 。我们把式子移动一下,得到:

$$v_{x_i}-s_i=(-v_{y_i})$$

$$(-v_{y_i})+s_i=v_{x_i}$$

$$v_{y_i}-s_i=(-v_{x_i})$$

$$(-v_{x_i})+s_i=v_{y_i}$$

  我们使节点 $1$ 作为初始节点,即令 $v_1=\alpha$ 。

  我们考虑将每一个点拆成两个点,一个点记录其正的权值(即 $v_i=\alpha + k$ 时,记录的值为 $k$ ),另一个点记录其负权值(即 $-v_i=\alpha+k$ ,记录的值为 $k$)。

  然后我们对于每一条边,拆成上述四条有向边。

  然后 bfs 一遍把每一个点与 $\alpha$ 的关系求出来。这里注意一点,如果到达一个点有两条距离不同的路径,那么显然答案为 $0$ 。(条件冲突)

  然后我们得到了一些数据。

  我们考虑去解决那些拆点之后两个节点都被访问的节点。

  对于每一个这样的节点,我们可以解出唯一的 $\alpha$ ,如果所有节点的解有不同,那么答案显然是 $0$ 。否则答案显然是 $1$ 。

  请您先思索一下在选中下面黑色矩形区域内的字看下面的话。

  这样是错的!!我就是挂在这里了。我们不能这么着急的确定答案是 $1$ 。因为我们还需要满足所有点权均为正整数。所以我们还需要判一判。

  然后就只剩下二分图的情况了。

  对于这种情况,我们只需要根据每一个节点与初始节点 $1$ 的关系,根据“正整数”这个条件更新 $\alpha$ 的取值范围。最后输出即可。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=400005;
struct Gragh{
int cnt,y[N],z[N],nxt[N],fst[N];
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void add(int a,int b,int c){
y[++cnt]=b,z[cnt]=c,nxt[cnt]=fst[a],fst[a]=cnt;
}
}g;
int n,m;
int q[N],head,tail;
LL dis[N];
LL INF=10000000000000000LL;
void out0(){
puts("0");
exit(0);
}
void SPFA(int S){
for (int i=1;i<=n*2;i++)
dis[i]=INF;
head=tail=0;
q[++tail]=S;
dis[S]=0;
while (head!=tail){
int x=q[++head],y;
for (int i=g.fst[x];i;i=g.nxt[i]){
int y=g.y[i];
if (dis[y]!=dis[x]+g.z[i]){
if (dis[y]!=INF)
out0();
dis[y]=dis[x]+g.z[i];
q[++tail]=y;
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
g.clear();
for (int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g.add(a,b+n,-c);
g.add(b+n,a,c);
g.add(b,a+n,-c);
g.add(a+n,b,c);
}
SPFA(1);
LL v=INF;
for (int i=1;i<=n;i++)
if (dis[i]!=INF&&dis[i+n]!=INF){
LL A=dis[i],B=dis[i+n];
if ((A+B)%2LL)
out0();
LL x=-(A+B)/2LL;
if (x!=v)
if (v==INF)
v=x;
else
out0();
}
if (v!=INF){
int f=1;
for (int i=1;i<=n;i++){
if (dis[i]!=INF)
if (v+dis[i]<=0)
f=0;
if (dis[i+n]!=INF)
if (v+dis[i+n]>=0)
f=0;
}
printf("%d",f);
return 0;
}
LL MIN=1,MAX=INF;
for (int i=1;i<=n;i++)
if (dis[i]!=INF)
MIN=max(MIN,-dis[i]+1);
else
MAX=min(MAX,-dis[i+n]-1);
printf("%lld",max(MAX-MIN+1,0LL));
return 0;
}

  

AtCoder SoundHound Inc. Programming Contest 2018 E + Graph (soundhound2018_summer_qual_e)的更多相关文章

  1. SoundHound Inc. Programming Contest 2018

    A - F Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement You are give ...

  2. ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syria, Lattakia, Tishreen University, April, 30, 2018

    ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syr ...

  3. German Collegiate Programming Contest 2018​ B. Battle Royale

    Battle Royale games are the current trend in video games and Gamers Concealed Punching Circles (GCPC ...

  4. The North American Invitational Programming Contest 2018 D. Missing Gnomes

    A family of nn gnomes likes to line up for a group picture. Each gnome can be uniquely identified by ...

  5. The North American Invitational Programming Contest 2018 H. Recovery

    Consider an n \times mn×m matrix of ones and zeros. For example, this 4 \times 44×4: \displaystyle \ ...

  6. The North American Invitational Programming Contest 2018 E. Prefix Free Code

    Consider nn initial strings of lower case letters, where no initial string is a prefix of any other ...

  7. AtCoder diverta 2019 Programming Contest 2

    AtCoder diverta 2019 Programming Contest 2 看起来我也不知道是一个啥比赛. 然后就写写题解QWQ. A - Ball Distribution 有\(n\)个 ...

  8. German Collegiate Programming Contest 2018​ C. Coolest Ski Route

    John loves winter. Every skiing season he goes heli-skiing with his friends. To do so, they rent a h ...

  9. 【AtCoder】M-SOLUTIONS Programming Contest

    M-SOLUTIONS Programming Contest A - Sum of Interior Angles #include <bits/stdc++.h> #define fi ...

随机推荐

  1. 百度echarts插件x轴坐标显示不全决解方法

    X轴显示不全: xAxis.axisLabel.interval number, Function [ default: 'auto' ] 坐标轴刻度标签的显示间隔,在类目轴中有效. 默认会采用标签不 ...

  2. 重启报错:Failed to open /dev/initctl: No such device or address

    [root@WEB-APP-REP-MASTER ~]# rebootError getting authority: Error initializing authority: Error call ...

  3. WebSocket异步通讯,实时返回数据

    第一种方式 // 服务端: //var listener = new HttpListener(); // listener.Prefixes.Add("http://*:8080/&quo ...

  4. Android源码分析一 Android系统架构

    一 Android系统架构 Linux内核层(Linux Kernel):Android系统基于Linux2.6内核,这一层为Android设备各种硬件提供了底层驱动,如显示驱动.音频驱动.照相机驱动 ...

  5. 弹框勾选datatable中的数据,点击保存后添加到另一个表中,同一个页面

    需求描述:做编辑的时候,点击添加按钮,弹出数据表table2,勾选弹出框中的数据,点击保存后能够添加到table1中,并且已经被添加到table1中的数据,在弹出框中显示已选,checkbox隐藏:t ...

  6. CF1019C

    好玄学的东西... 核心思想:for循环! 首先,我们从前向后扫所有的点,如果这个点没被标记成不可用就把这个点标记成已使用,然后把所有与这个点直接相连的点标记成不可用 接下来,我们从后向前扫所有的点, ...

  7. linux添加自定义命令

    想添加一个命令, 比如我输入 cdms 按回车, 然后就执行了: cd /mnt/gopath/src/test/app/ 这条命令方法: vi /etc/bashrc 在文件末尾添加 alias c ...

  8. C++中explicit关键字的作用 (转)

    explicit用来防止由构造函数定义的隐式转换. 要明白它的作用,首先要了解隐式转换:可以用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换. 例如: class things { ...

  9. Android 第二波

    三面,4个技术人员面试的问题不是很难.问题如下: 1. Service两种方式的区别 首先说service分为两种,一种是绑定的一种是非绑定的非绑定的生命周期是 onCreate(),onStartC ...

  10. dnsjava usage

    linux dig 命令使用方法 https://www.imooc.com/article/26971?block_id=tuijian_wz https://jimwayne.blogspot.c ...