b.病毒感染
題意:給出一顆所有路徑都為1的樹,讓你找出到其餘點距離和最小的點,若存在多個,都輸出。
暴力法:跑n邊迪傑斯特拉,n>=5e5,顯然不行。
試著畫圖模擬找思路:
上圖中,1到其餘各點的距離和為7(1+1+1+1+1+2),2到其餘各點的距離和為10(1+1+2+2+2+2),因為題目保證了各路徑長度都為1,顯然,從1到2的過程中,增加的路徑是1、3、4、5、6五個點貢獻的,減少的路徑則是2、7兩個點貢獻的。也就是ans[2]=ans[1]+5-2。其中的5和2,就是結點2「左邊」的結點數量和「右邊」的節點數量。
這樣一來,這個問題就分成了下面幾個步驟:
計算出每個結點「左邊」的結點數量和「右邊」的節點數量。
計算出某個結點x的答案。
通過結點x來遞推其餘結點 。
ac**:
/*
* @author: hesorchen
* @date: 2020-04-14 10:33:26
* @lastedittime: 2020-07-01 15:49:29
* @link:
*/#include
using
namespace std;
#define inf 0x3f3f3f3f
#define pll pair
#define ll long long
#define ios \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
ll head[
500010
], ct =1;
struct node
g[500010];
void
add(ll u, ll v)
ll cnt[
500010];
ll dis[
500010];
bool vis[
500010];
void
dfs1
(ll s)
//計算出每個結點「左邊」的結點數量和「右邊」的節點數量
}pll a;
queue q;
void
bfs(ll s, ll sum)
//bfs求出結點1到其餘各點的距離}}
}ll n, m;
void
bfs2
(ll pos, ll sum)
//遞推}}
intmain()
vis[1]
=1;dfs1(1
);fill
(vis, vis +
500010,0
);bfs(1,
0);//bfs求出結點1到其餘各點的距離和,使用結點1遞推其他點
ll sum_1 =0;
for(
int i =
1; i <= n; i++
) sum_1 +
= dis[i]
;fill
(vis, vis +
500010,0
);fill
(dis, dis +
500010,0
);bfs2(1
, sum_1)
;//遞推
ll minn = inf;
for(
int i =
1; i <= n; i++
) minn =
min(minn, dis[i]);
for(
int i =
1; i <= n; i++)if
(minn == dis[i]
) cout << i <<
' ';
cout << endl;
return0;
}
B 病毒感染
有一天clccle和rqy走在某個國家的街頭上,機智的rqy卻發現周圍的行人不太對勁,他們嘴裡念念有詞,說著 sqn tql 一邊漫無目的的行走,clccle也發現了這一點,卻驚訝的發覺這種奇怪的病毒會向周圍的城市,最終會感染整個國家,因為網路已經崩潰,所以她們忘記了自己所在的城市,她們唯一知道的是...
病毒感染監測
include include include using namespace std s的第乙個字元和t比較,不相等就和第二個比較,如果一旦有不相等的就繼續比較,設定乙個標記,如果一直沒有就更新一下s的順序 void change string s,int count s length 1 a c...
JSOI2016病毒感染
1.題目大意 有1 n的村莊,每個村莊在不 的情況下每天死 a i 人,到達乙個村莊可以 或跳過,若跳過,再回頭時只能一直走回這個村莊,然後才能重新往前走,求最少死亡人數。2.題目分析 我們定義f i 為前 i 個村莊全部治好的最小代價。令j i,在 1 i 內列舉回頭點,因此我們再定義乙個 g i...