【題解】【總結】P1330封鎖陽關大學&&圖論小總結
【題解】【總結】P1330 封鎖陽光大學 &&圖論小總結
這道題其實有一點點難度,不過我能經過思考做出來說明還是沒有普及組\(D1T1\)難度的。
考慮一條邊的兩邊要有且僅有一個點被選中...這不就是染色嗎?想到此,聰明的你一定就知道怎麽做了。
這題唯一的坑點就是不一定圖是聯通的,所以要\(for\)一下所有點去\(bfs\)。
這種題我還\(wa\)了一次,而且如果不是我下了數據還調不出來...
思考一下為什麽沒有一遍過此題,還是因為思維不夠完善。圖論的題目,有什麽坑點呢?在這裏總結一下:
- 圖不聯通。有這個圖的連通性意識就不會被坑。這裏包括了森林的情況。
- 有自環的重邊。這個是毒瘤出題人幹的事情,不能被坑了。
- 存在負環,要判斷一下。
- 樹的根被指定了!
- 邊數可能比你想像的要多。
- \(spfa\)已經死了QAQ!
- \(fr\)和\(to\)的位置調換了。涼心出題人!
解決圖論的問題,可以通過什麽辦法呢?
- \(Tarjin\)求環求強連通分量。
- 最短路算法。(還有那種取對數的)
- 縮點+\(DAG\) \(DP\)
- 拓撲排序
- 並查集
- 最小生成樹,實際上和擬陣聯系起來。
- 樹形\(dp\),實際上和上面那個很像的
- 樹上倍增。\(lca\),\(st\)表啊之類的。
- 樹上差分。我也不是很熟。
- 點分治。解決樹上路徑計數問題等。
- 樹鏈剖分。同樣也是樹上路徑,還可以順便解決子樹等問題。
- 樹上莫隊。神奇的算法。
- 正難則反!圖論的題維護加邊比較容易,維護減邊就比較麻煩。反著來!
- 網絡流。(主要是建模難 QAQ)
---cpp
include<bits/stdc++.h>
using namespace std;
define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
define Max(a,b) ((a)<(b)?(b):(a))
define Min(a,b) ((a)<(b)?(a):(b))
define midd register int mid=(l+r)>>1
define TMP template < class ccf >
TMP inline ccf qr(ccf b){
char c=getchar();
int q=1;
ccf x=0;
while(c<48||c>57)
q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)
x=x*10+c-48,c=getchar();
return q==-1?-x:x;
}
const int maxn=10005;
const int maxm=100005;
struct E{
int to,nx;
}e[maxm<<1];
int head[maxn];
int col[maxn];
int cnt;
int n,m;
inline void add(int fr,int to,bool f){
e[++cnt]=(E){to,head[fr]};
head[fr]=cnt;
if(f)
add(to,fr,0);
}
queue < int > q;
inline int bfs(int S){
q.push(S);
col[S]=-1;
int colcnt=0,tolcnt=0;
while(!q.empty()){
register int now=q.front();
colcnt+=(col[now]==1);
tolcnt++;
q.pop();
ERP(t,now)
if(col[e[t].to]!=0&&col[e[t].to]!=-col[now])
return -1;
else
if(col[e[t].to]==0)
q.push(e[t].to),col[e[t].to]=-col[now];
}
return Min(colcnt,tolcnt-colcnt);
}
int main(){
ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
endif
n=qr(1);
m=qr(1);
for(register int t=1,t1,t2;t<=m;++t){
t1=qr(1);
t2=qr(1);
add(t1,t2,1);
}
int ans=0,k;
RP(t,1,n)
if(col[t]==0)
if((k=bfs(t))==-1)
return puts("Impossible"),0;
else
ans+=k;
cout<<ans<<endl;
return 0;
}
【題解】【總結】P1330封鎖陽關大學&&圖論小總結