打击犯罪(信息学奥赛一本通-T1386)
生活随笔
收集整理的這篇文章主要介紹了
打击犯罪(信息学奥赛一本通-T1386)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【題目描述】
某個地區有n(n≤1000)個犯罪團伙,當地警方按照他們的危險程度由高到低給他們編號為1-n,他們有些團伙之間有直接聯系,但是任意兩個團伙都可以通過直接或間接的方式聯系,這樣這里就形成了一個龐大的犯罪集團,犯罪集團的危險程度由集團內的犯罪團伙數量唯一確定,而與單個犯罪團伙的危險程度無關(該犯罪集團的危險程度為n)。現在當地警方希望花盡量少的時間(即打擊掉盡量少的團伙),使得龐大的犯罪集團分離成若干個較小的集團,并且他們中最大的一個的危險程度不超過n/2。為達到最好的效果,他們將按順序打擊掉編號1到k的犯罪團伙,請編程求出k的最小值。
【輸入】
第一行一個正整數n。接下來的n行每行有若干個正整數,第一個整數表示該行除第一個外還有多少個整數,若第i行存在正整數k,表示i,k兩個團伙可以直接聯系。
【輸出】
一個正整數,為k的最小值。
【輸入樣例】
7
2 2 5
3 1 3 4
2 2 4
2 2 3
3 1 6 7
2 5 7
2 5 6
【輸出樣例】
1
【源程序】
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<cstdlib> #include<queue> #include<set> #include<vector> #define INF 0x3f3f3f3f #define PI acos(-1.0) #define N 1001 #define MOD 123 #define E 1e-6 using namespace std; struct node{int pre;int next; }a[N*N]; int father[N]; int head[N],ans[N]; int cnt; void add(int x,int y) {cnt++;a[cnt].pre=y;a[cnt].next=head[x];head[x]=cnt;cnt++;a[cnt].pre=x;a[cnt].next=head[y];head[y]=cnt; } int Find(int x) {if(father[x]==x)return x;return father[x]=Find(father[x]); } int main() {int n;cin>>n;for(int i=1;i<=n;i++){father[i]=i;ans[i]=1;int m;cin>>m;for(int j=1;j<=m;j++){int k;cin>>k;add(i,k);}}for(int i=n;i>=1;i--){int x=Find(i);int k=head[i];while(k!=0){int j=a[k].pre;if(j>i){int y=Find(j);if(x!=y){father[y]=x;ans[x]+=ans[y];if(ans[x]>n/2){cout<<i<<endl;return 0;}}}k=a[k].next;}}return 0; }?
總結
以上是生活随笔為你收集整理的打击犯罪(信息学奥赛一本通-T1386)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 重建道路(洛谷-P1272)
- 下一篇: 大整数减法(信息学奥赛一本通-T1169