1299 監獄逃離
codility
基準時間限制:1 秒 空間限制:131072 kb 分值: 320
難度:7級演算法題
監獄有n條道路連線n + 1個交點,編號0至n,整個監獄被這些道路連在一起(任何2點之間都有道路),人們通過道路在交點之間走來走去。其中的一些交點只有一條路連線,這些點是監獄的出口。在各個交點中有m個點住著犯人(m <= n + 1),剩下的點可以安排警衛,有警衛把守的地方犯人無法通過。給出整個監獄的道路情況,以及犯人所在的位置,問至少需要安排多少個警衛,才能保證沒有1個犯人能夠逃到出口,如果總有犯人能夠逃出去,輸出-1。
如上圖所示,點1,6 住著犯人,0,4,5,7,8是出口,至少需要安排4個警衛。
input
第1行:2個數n, m中間用空格分隔,n表示道路的數量,m表示犯人的數量(1<= n <= 100000, 0 <= m <= n + 1)。output之後n行:每行2個數s, e中間用空格分隔,表示點編號為s的點同編號為e的點之間有道路相連。(0 <= s, e <= n)。
之後的m行,每行1個數pi,表示編號為pi的點上有犯人。
輸出1個數對應最少需要多少警衛才能不讓犯人逃出監獄。input示例
8 2output示例0 11 2
2 33 4
3 52 6
6 86 7
16
4以任意乙個葉子節點作為根節點
mark[u]=0:以u為根的子樹的犯人能到達u,但不存在從u到葉子的路徑
mark[u]=1:以u為根的子樹中的犯人不能到達u,但存在從u到葉子的路徑
mark[u]=2:以u為根的子樹中的犯人不能到達u,且不存在從u到葉子的路徑
u有犯人,子節點不能存在通往葉子的路徑
u沒有犯人,如果子節點有犯人能到u且有路徑從子節點到葉子,封鎖u
根節點狀態為0,則封鎖根節點
#include#include#includeusing namespace std;
const int inf = 0x3f3f3f3f;
const int mx = 2e5 + 5;
struct edgee[mx*2];
int head[mx],tot;
int son[mx][3],mark[mx],p[mx],in[mx],ans;
void init()
void add(int u,int v)
void dfs(int u,int fa)
for(int i=head[u];~i;i=e[i].nxt)
//if(u==1) printf("%d\n",son[u][1]);
if(p[u]) ans+=son[u][1]; //有犯人,封鎖所有可以通往葉子的兒子
else if(son[u][0]&&son[u][1])
else if(son[u][0]) mark[u]=0;
else if(son[u][1]) mark[u]=1;
else mark[u]=2;
}int main()
int flag=1;
for(int i=1,u;i<=n;i++)
p[u]=1;
}if(flag)
printf("%d\n",ans);
}return 0;
}
51nod 1299 監獄逃離
監獄有n條道路連線n 1個交點,編號0至n,整個監獄被這些道路連在一起 任何2點之間都有道路 人們通過道路在交點之間走來走去。其中的一些交點只有一條路連線,這些點是監獄的出口。在各個交點中有m個點住著犯人 m n 1 剩下的點可以安排警衛,有警衛把守的地方犯人無法通過。給出整個監獄的道路情況,以及犯...
51Nod 1299 監獄逃離
這其實是一道樹形dp的神仙題。然後開始推推推,1 hour later樣例都過不了 然後仔細一看題目,貌似像乙個最小割模型,然後5min想了想建圖 首先拆點,將每個點拆成進和出兩個,然後連邊,邊權即為 1 表示割掉這條邊的代價 然後設超級源 s 讓 s 向所有犯人的出點 因為犯人的點無法割去 連邊,...
51nod 1299 監獄逃離
監獄有n條道路連線n 1個交點,編號0至n,整個監獄被這些道路連在一起 任何2點之間都有道路 人們通過道路在交點之間走來走去。其中的一些交點只有一條路連線,這些點是監獄的出口。在各個交點中有m個點住著犯人 m n 1 剩下的點可以安排警衛,有警衛把守的地方犯人無法通過。給出整個監獄的道路情況,以及犯...