給你n個點$(n\leq100000)$所構成的邊帶權的無向圖,每個點都有黑或白兩種顏色之一,其中黑記為1,白記為0.現在要你選擇一些邊(選擇一條邊的代價即為此邊權值),用這些邊構成新的圖,使得新圖中每個白點都與黑點聯通,且每個白點到距離其最近的黑點的距離等於原圖中的最短距離.若不存在這樣的圖,輸出impossible.
這題蠻神奇的,思路也不錯,讓我們來分析分析.首先,要求出每個白點到其最近的黑點的最短距離,我們可以通過新建乙個超級點t,與每個黑點相連且邊權為0.spfa求出最短距離,然後想辦法構圖.我們來分析一下白點:對於乙個白點$x$,加入到其最近的黑點與其直接相連,那直接將邊權統計進去;加入這個白點與其它白點$y$相連,那白點y到黑點的最短路徑一定是白點x到黑點的最短路徑的子集,且僅差一條邊,這條邊將點$x$與$y$相連,所以只需將此邊計入ans,因為其餘路徑點$y$可以統計.
#include#include#include
#include
#include
#include
#include
#define r register
#define next exntttttttttttttttttttttt
#define debug puts("mlg")
using
namespace
std;
typedef
long
long
ll;typedef
long
double
ld;typedef unsigned
long
long
ull;
inline ll read();
inline
void
write(ll x);
inline
void
writesp(ll x);
inline
void
writeln(ll x);
ll n,m,t;
ll col[
200000
];ll from[
500000],to[500000],head[500000],tot=1,c[500000],next[500000
];inline
void
add(ll x,ll y,ll z)
ll d[
500000],pre[500000],last[500000
];queue
q;bool vis[500000
];inline
void
spfa()}}
}}ll ans;
intmain()
}for(r ll i=1,x,y,z;i<=m;i++)
spfa();
for(r ll i=1;i<=n;i++)if(!col[i]&&d[i]==d[0])
for(r ll x=1;x<=n;x++)
writeln(ans);
}inline ll read()while(ch>='
0'&&ch<='
9')return x*t;}
inline
void write(ll x)if(x<=9)write(x/10);putchar(x%10+'0'
);}inline
void writesp(ll x)
inline
void writeln(ll x)
20200721NOIP提高組模擬T1 矩陣
給你乙個數a,以及一串全是數字的字串以構造矩陣c,c i j a i a j a k 表示字串中第k位所代表的數字 請你求出權值之和恰好為a的子矩陣個數.此題比較有意思.題目要我們求的答案即滿足 sum sum c i j a 的四元組 x,y,u,v 個數.接下來我們分析一下這個式子 sum su...
NOIP提高組 矩陣
在麥克雷的面前出現了乙個有n m個格仔的矩陣,每個格仔用 或 表示,表示這個格仔可以放東西,則表示這個格仔不能放東西。現在他拿著一條1 2大小的木棒,好奇的他想知道對於一些子矩陣,有多少種放木棒的方案。因為棍子是1 2的,所以很容易就能發現,兩個被分割的塊,除了跨越兩個塊擺放木棍的方案數會對答案有影...
NOIP提高組2005 過河
過河 river 問題描述 在河上有一座獨木橋,乙隻青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點 0,1,l 其中l是橋的長度 座標為0的點表示橋的起點,座標為l的...