原文链接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. 【原创】大数据基础之Flume(2)应用之kafka-kudu

    应用一:kafka数据同步到kudu 1 准备kafka topic # bin/kafka-topics.sh --zookeeper $zk:2181/kafka -create --topic ...

  2. python基础--管理目录与文件

    1) 文件夹 os.listdir() #显示文件夹下所有文件 os.getcwd() #获取当前工作目录 os.chdir() #切换目录 os.mkdir() #建立目录 os.path.exis ...

  3. python-迭代器、生成器、内置函数及面向过程编程

    一.迭代器 迭代器是迭代取值的工具,迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的. 为什么要用迭代器呢? 1.可以不依赖索引取值 2.同一时刻在内存中只有一个值,不会过多的占用内存 如何 ...

  4. 【Android开发经验】android:windowSoftInputMode属性具体解释

    本文章来自CSDN博客:http://blog.csdn.net/zhaokaiqiang1992.转载请注明地址! 在前面的一篇文章中,简单的介绍了一下怎样实现软键盘不自己主动弹出,使用的方法是设置 ...

  5. 姿势摆好,一招学会android的布局优化!

    作为android应用来讲,无论应用本身多么美观,功能多么强大,内容多么丰富.但如果App本身打开界面缓慢超过手机16ms刷新一次页面的时间,就会产生卡顿.用户体验都会变得极差,导致用户量减少.所以我 ...

  6. PID控制器开发笔记之九:基于前馈补偿的PID控制器的实现

    对于一般的时滞系统来说,设定值的变动会产生较大的滞后才能反映在被控变量上,从而产生合理的调节.而前馈控制系统是根据扰动或给定值的变化按补偿原理来工作的控制系统,其特点是当扰动产生后,被控变量还未变化以 ...

  7. Confluence 6 内存使用和需求和一些问题

    系统备份和恢复 Confluence  的备份和恢复是与数据库中数据量的大小有关.这个操作可能会对 Confluence 的性能产生很多关键性的影响并且大量消耗内存.如果你在 Confluence 的 ...

  8. Android UiAutomator 快速调试

    背景:在Eclipse中不能直接运行Uiautomator工程,所以每次编写一份用例都要进行手动输入命令,很烦.调试起来不仅繁琐还浪费时间.网上找到一份快速调试的代码UiAutomatorHelper ...

  9. 第十四单元 Linux网络原理及基础设置

    ·ifconfig命令来维护网络(详见linux系统管理P422) 1) 掌握ifconfig命令的功能:显示所有正在启动的网卡的详细信息或设定系统中网卡的IP地址.2) 灵活应用ifconfig命令 ...

  10. Pycharm同步本地代码至GitHub

    注册github账号 github地址,进入注册账号 安装git Windows下载地址1 Windows下载地址2 在官方下载完后,双击exe文件进行安装,安装到Windows Explorer i ...