第一次爆零
前言:打代碼慢沒關系,除非你不用心
一開始打了好多,但由於孫姓同學(gavensun.com)運行了一個惡意程序,然後本篇博文並沒有保存,所以前言就說這麽多
第一題,註意數據範圍,不要吊兒郎當
第二,三題(並查集求聯通塊:不要亂寫,撞對垃圾樣例並不一定對
2
道路
1000ms/128MB
M市有 n個城鎮,同時有 m條道路(無向),城鎮之間可以通過一條或多條道路到達。為了全面建設小
康社會,現要新建設一些道路,使得所有城鎮之間兩兩可以互相到達。
請你計算出最少還需要建設多少條道路
輸入格式:
第一行:兩個正整數,分別是城鎮數目 n(n<1000)和道路數目 m(m <= n * (n – 1)/2));隨後的m行對應 m條道路,每行給出兩個正整數,分別是道路相連的兩個城鎮編號。城鎮從 1到 N編號。
兩個城市間可以有多條道路相通。
輸出格式:一行一個整數。為最少需要建設的道路。
1 #include<cstdio> 2 #include<algorithm> 3 #define DEEEEEEEE 4 using namespace std; 5 const int MAXN = 1000+9; 6 const int MAXM = 500000+9; 7 8 int n,m,ans; 9 int fa[MAXN]; 10 boolvisit[MAXN]; 11 12 int father(int x) { 13 if(x == fa[x]) return x; 14 return fa[x] = father(fa[x]); 15 } 16 17 int main() { 18 #ifdef DEEEEEEEE 19 freopen("b.in","r",stdin); 20 freopen("b.out","w",stdout); 21 #endif 22 scanf("%d%d",&n,&m); 23for(int i = 1; i <= n; i++) fa[i] = i; 24 int fx,fy; 25 for(int i = 1, x, y; i <= m; i++) { 26 scanf("%d %d",&x,&y); 27 fx = father(x), fy = father(y); 28 fa[fx] =fy;//把道路的代表元素聯通 29 } 30 for(int i = 1; i <= n; i++) { // 求聯通塊個數 31 if(!visit[father(i)]) {//先寫father(i) 這才把fa[i]算出來 32 visit[fa[i]] = 1; 33 ans++; 34 } 35 } 36 printf("%d",ans-1);//ans個聯通塊,最少需要連ans-1條道路 37 return 0; 38 }
3.
現在一個平面上畫了 n 個矩形。每一個矩形的兩邊都與坐標軸相平行,且矩形定點的坐標均為整數。現定
義滿足如下性質的圖形為一個塊:
1. 每一個矩形都是一個塊;
2. 如果兩個塊有一段公共的部分,那麽這兩個塊就會形成一個新的塊,否則這兩個塊就是不同的。
示例:
圖 1矩形形成了兩個不同的塊。圖 2矩形形成了一個塊。找不同塊的個數
#include<cstdio> #include<algorithm> #define DEEEEEEEE using namespace std; const int MAXN = 7000+9; int n,ans; int fa[MAXN]; bool visit[MAXN]; int father(int x) { if(x == fa[x]) return x; return fa[x] = father(fa[x]); } struct node{ int x1,y1,x2,y2; }e[MAXN]; bool judge(int x1,int y1, int x2, int y2, int x111, int y111, int x222, int y222) { //找關系的時候冷靜一點,不要慌 if(x2<x111 || x1>x222 || y1>y222 || y2<y111 ) return 0;//沒有一點相交 if( (x1==x222 || x2==x111) && (y1==y222 || y2==y111) ) return 0;//相交一點 return 1; } int main() { #ifdef DEEEEEEEE freopen("c.in","r",stdin); freopen("c.out","w",stdout); #endif scanf("%d",&n); for(int i = 1; i <= n; i++) fa[i] = i; int x1,y1,x2,y2,x111,y111,x222,y222; // 矩形1號 矩形2號 int f1,f2; for(int i = 1; i <= n; i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); e[i].x1 = x1, e[i].x2 = x2, e[i].y1 = y1, e[i].y2 = y2; for(int j = 1; j < i; j++) { x111 = e[j].x1 , y111 = e[j].y1 , x222 = e[j].x2 , y222 = e[j].y2 ; if(judge(x1,y1,x2,y2,x111,y111,x222,y222) ) { f1 = father(i), f2 = father(j); fa[f1] = f2; } } } for(int i = 1; i <= n; i++) { if(!visit[father(i)]) { visit[fa[i]] = 1; ans++; } } printf("%d",ans); return 0; }
第四題:分層圖(仔細分析題目,不要看見那麽多的條件就害怕
消失的 c題(c.cpp/c.in/c.out)
1000ms/128MB
題目描述
N 個蟲洞,M 條單向躍遷路徑。從一個蟲洞沿躍遷路徑到另一個蟲洞需要消耗一定量的燃料和 1 單
位時間。蟲洞有白洞和黑洞之分。設一條躍遷路徑兩端的 蟲洞質量差為 delta。
1.從白洞躍遷到黑洞,消耗的燃料值減少 delta,若該條路徑消耗的燃料值變為負數的話,取為 0。
2.從黑洞躍遷到白洞,消耗的燃料值增加 delta。
3.路徑兩端均為黑洞或白洞,消耗的燃料值不變化。
每過 1 單位時間黑洞變為白洞,白洞變為黑洞。
在飛行過程中,可以選擇在一個蟲洞停留 1 個單位時間,如果當前為白洞,則不消耗燃料,否則消
耗 s[i]的燃料。現在請你求出從 蟲洞 1 到 N 最少的燃料消耗,保證一定存在 1 到 N 的路線。
輸入格式第 1 行:2 個正整數 N,M
第 2 行:N 個整數,第 i 個為 0 表示蟲洞 i 開始時為白洞,1 表示黑洞。
第 3 行:N 個整數,第 i 個數表示蟲洞 i 的質量 w[i]。
第 4 行:N 個整數,第 i 個數表示在蟲洞 i 停留消耗的燃料 s[i]。第 5..第 M+4 行:每行 3 個整數,u,v,k,表示在沒有影響的情況下,從蟲洞 u到蟲洞 v 需要消耗燃料 k。
輸出格式
一個整數,表示最少的燃料消耗。
樣例輸入
4 5
1 0 1 0
10 10 100 10
5 20 15 10
1 2 30
2 3 40
1 3 20
1 4 200
3 4 200
樣例輸出
130
數據範圍
對於 30%的數據: 1<=N<=100,1<=M<=500
對於 60%的數據: 1<=N<=1000,1<=M<=5000
對於 100%的數據: 1<=N<=5000,1<=M<=30000
其中 20%的數據為 1<=N<=3000 的鏈
1<=u,v<=N, 1<=k,w[i],s[i]<=200
樣例說明
按照 1->3->4 的路線。
第一次爆零