洛谷 P10P1343 地震逃生 改錯
阿新 • • 發佈:2018-05-20
無法 break use 發生 最大 print 現在 int 網絡流 描述一條邊,分別代表從\(a\)點到\(b\)點有一條邊,且可容納\(c\)名學生。
,\(x\)為偶
\(x\) \(nor\) \(1=x-1\),\(x\)為奇
P1343 地震逃生
題目描述
汶川地震發生時,四川**中學正在上課,一看地震發生,老師們立刻帶領x名學生逃跑,整個學校可以抽象地看成一個有向圖,圖中有\(n\)個點,\(m\)條邊。1號點為教室,\(n\)號點為安全地帶,每條邊都只能容納一定量的學生,超過樓就要倒塌,由於人數太多,校長決定讓同學們分成幾批逃生,只有第一批學生全部逃生完畢後,第二批學生才能從1號點出發逃生,現在請你幫校長算算,每批最多能運出多少個學生,\(x\)名學生分幾批才能運完。
輸入輸出格式
輸入格式:
第一行3個整數\(n,m,x(x<2^{31},n<=200,m<=2000)\);以下\(m\)行,每行三個整數\(a,b,c\)
輸出格式:
兩個整數,分別表示每批最多能運出多少個學生,\(x\)名學生分幾批才能運完。如果無法到達目的地(\(n\)號點)則輸出“\(Orz\) \(Ni\) \(Jinan\) \(Saint\) \(Cow!\)”
很明顯網絡流的裸題。
前幾天看到對前向星用\(x\) \(nor\) 1\(找反邊,覺得很方便,遂用一下,用想到很久沒打\)dinic$了,就決定打打(以前都是偷懶打EK的)
不過這樣找反邊\(head\)最開始時得賦\(-1\),而且邊的邊界也是-1
因為
\(x\) \(nor\) \(1=x+1\)
\(x\) \(nor\) \(1=x-1\),\(x\)為奇
得用上0
然後我.....
我是得多智障才這樣,居然樣例還對了...
還有一點,最後算答案是\((ans-1)/\)最大流\(+1\)
我沒給那個\(ans\)減一下
code:
#include <cstdio> #include <queue> #include <cstring> using namespace std; const int N=204; const int M=2004; const int inf=0x3f3f3f3f; struct Edge { int w,to,next; }edge[M*2]; struct node { int cnt,u; }S[N]; int n,m,X,cnt=-1,head[N]; int top=0; void push(int cnt0,int u0) {S[++top].cnt=cnt0,S[top].u=u0;} void pop() {top--;} int read() { int x=0;char c=getchar(); while(c<‘0‘||c>‘9‘) c=getchar(); while(c>=‘0‘&&c<=‘9‘) {x=x*10+c-‘0‘;c=getchar();} return x; } void add(int u,int v,int w) { edge[++cnt].next=head[u],edge[cnt].to=v,edge[cnt].w=w,head[u]=cnt; edge[++cnt].next=head[v],edge[cnt].to=u,edge[cnt].w=0,head[v]=cnt; } int dep[N],used[N],ans=0; queue <int > q; bool bfs() { memset(dep,0,sizeof(dep)); while(!q.empty()) q.pop(); q.push(1);dep[1]=1; while(!q.empty()&&q.front()!=n) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to,w=edge[i].w; if(!dep[v]&&w) { dep[v]=dep[u]+1; q.push(v); } } } return !q.empty(); } int main() { memset(head,-1,sizeof(head)); n=read(),m=read(),X=read(); int u,v,w; for(int i=1;i<=m;i++) { u=read(),v=read(),w=read(); add(u,v,w); } while(bfs()) { memset(used,0,sizeof(used)); top=0; push(head[1],1); while(top) { if(S[top].u==n) { int m_min=inf,id; for(int i=2;i<=top;i++) if(edge[S[i].cnt].w<m_min) { m_min=edge[S[i].cnt].w; id=i; } ans+=m_min; for(int i=2;i<=top;i++) { edge[S[i].cnt].w-=m_min; edge[(S[i].cnt)^1].w+=m_min; } used[n]=0; top=max(0,id-1); } else { int u=S[top].u; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to,w=edge[i].w; if(!used[v]&&w&&dep[v]==dep[u]+1) { used[v]=1; push(i,v); break; } } if(S[top].u==u) top--; } } } if(ans==0) {printf("Orz Ni Jinan Saint Cow!\n");return 0;} printf("%d %d\n",ans,(X-1)/ans+1); return 0; }
2018.5.20
洛谷 P10P1343 地震逃生 改錯