p1403[noip2010]關押罪犯
s 城現有兩座監獄,一共關押著n 名罪犯,編號分別為1~n。他們之間的關係自然也極不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時 可能爆發衝突。我們用「怨氣值」(乙個正整數值)來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之間的積怨越多。如果兩名怨氣值為c 的罪犯 被關押在同一監獄,他們倆之間會發生摩擦,並造成影響力為c 的衝突事件。
每年年末,警察局會將本年內監獄中的所有衝突事件按影響力從大到小排成乙個列表,然後上報到s 城z 市長那裡。公務繁忙的z 市長只會去看列表中的第乙個事件的影響力,如果影響很壞,他就會考慮撤換警察局長。
在詳細考察了n 名罪犯間的矛盾關係後,警察局長覺得壓力巨大。他準備將罪犯們在兩座監獄內重新分配,以求產生的衝突事件影響力都較小,從而保住自己的烏紗
帽。假設只要處於同一監獄內的某兩個罪犯間有仇恨,那麼他們一定會在每年的某個時候發生摩擦。那麼,應如何分配罪犯,才能使z 市長看到的那個衝突事件的
影響力最小?這個最小值是多少?
輸入檔案的每行中兩個數之間用乙個空格隔開。
第一行為兩個正整數n 和m,分別表示罪犯的數目以及存在仇恨的罪犯對數。
接下來的m 行每行為三個正整數aj,bj,cj,表示aj 號和bj 號罪犯之間存在仇恨,其怨氣值為cj。資料保證1<=aj輸出共1 行,為z 市長看到的那個衝突事件的影響力。如果本年內監獄中未發生任何衝突事件,請輸出0。
4 61 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884
3512【資料範圍】
對於30%的資料有n≤ 15。
對於70%的資料有n≤ 2000,m≤ 50000。
對於100%的資料有n≤ 20000,m≤ 100000。
——————————————我是分割線————————————————————————
【解法一】
使用並查集,最快的方法。
一開始沒注意資料範圍,陣列開小了,導致最後4個點re,乙個多鐘頭才查出來t_t
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11tyvj 1403(1)#define maxn 100001
12#define f(i,j,k) for(int i=j;i<=k;i++)
13#define m(a,b) memset(a,b,sizeof(a))
14#define ff(i,j,k) for(int i=j;i>=k;i--)
15#define inf 0x7fffffff
16#define p 23333333333333333
17using
namespace
std;
18int
read()
21while(ch>='
0'&&ch<='9')
22return x*f;23}
24int
f[maxn];
25struct
sd26
edge[maxn];
32bool cmp(const sd& x,const sd&y)
3336
int find(int
x) 37
40int
head[maxn];
41int cnt=1;42
int addedge(int x,int y,int
v)43
51int
main()
5263
intx,y;
64for(int i=1;i<=n*2;i++)
65 f[i]=i;
66 sort(edge+1,edge+m+1
,cmp);
67 f(i,1
,m)75 f[y]=find(edge[i].a+n);
76 f[x]=find(edge[i].b+n);77}
78 cout<
<
79return0;
80 }
【解法二】
二分+二分圖染色
前向星儲存資訊,用a陣列單獨儲存怨氣值,增加0(若無衝突,則輸出0。
將a陣列從小到大排序,二份答案。
若當前大於等於mid的關係能滿足二分圖的要求(用到二分圖染色判定),則說明解小於等於mid,r=mid,否則說明解大於mid,就將l賦值為mid+1。
開了全域性變數n、m後在主函式中又開了一次,導致錯誤,只輸出0。又查了乙個鐘頭........(大哭)
1/*2tyvj 1403(2)problem:tyvj 1403
3by:s.b.s.4*/
5 #include6 #include7 #include8 #include9 #include10 #include11 #include12 #include13 #include14 #include15
#define maxn 200001
16#define f(i,j,k) for(int i=j;i<=k;i++)
17#define m(a,b) memset(a,b,sizeof(a))
18#define ff(i,j,k) for(int i=j;i>=k;i--)
19#define inf 0x7fffffff
20using
namespace
std;
21int
read()
24while(ch>='
0'&&ch<='9')
25return x*f;26}
27struct
edge
28edge[maxn];
33int
tot,it,n,m;
34int
head[maxn],b[maxn],a[maxn];
35bool
pd;36 inline void addedge(int x,int y,int
z)37
43int cmp(int a,int
b) 44
47 inline void dfs(int x,int
d)4864}
65}66}
67}68 inline bool ok(int
mm)69
78return
pd;79}80
intmain()
8197
//for(int i=1;i<=tot;i++)cout<98 a[1]=0
;99 sort(a+1,a+1+m,cmp);
100//
for(int i=1;i<=m+1;i++)cout<101
//cout<102
int left=1,right=m+1
,mid;
103while(left
104110 cout
111return0;
112}
113/*
1144 6
1151 4 2534
1162 3 3512
1171 2 28351
1181 3 6618
1192 4 1805
1203 4 12884
121*/
關押罪犯題解
題目 s城現有兩座監獄,一共關押著n名罪犯,編號分別為1 n。他們之間的關係自然也極不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時可能爆發衝突。我們用 怨 氣值 乙個正整數值 來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之間的積怨越多。如果兩名怨氣值為 c 的罪犯被關押在同一監...
noip2010 關押罪犯 題解
這道題的初始思路肯定會往貪心上面靠吧。很明顯首先需要對所有的衝突值從大到小排乙個序,因為是從小到大處理,所以肯定是衝突的放在兩個不同的監獄裡,一直到不得不衝突的為止。主要問題在於 不能直接通過標記罪犯所在的監獄編號來記錄衝突!因為你不能確定把當前罪犯放在監獄1裡或者監獄2裡,與後面的罪犯衝突的情況下...
題解 P1525 關押罪犯
這道題是一道比較好的並查集的題目,蒟蒻頓時感覺我學了乙個假的並查集。首先,這道題的意思是 給你 n 個點,將他們任意分成兩邊,求這些點之前權值最大的邊盡量的小,求這個值。我們如何用並查集來做呢?首先,我們將所有邊從大到小排序,對於每兩個點 x 和 y 我們將 x 和 y 的敵人放一起,x 的敵人和 ...