bzoj1001/luogu4001 狼抓兔子 (最小割/平面图最小割转对偶图最短路)

时间:2023-03-08 17:33:09

平面图转对偶图:先在原图中加一个s->t的边,然后对每个面建一个点,对每条分隔两个面的边加一条连接这两个面对应点的边,边权等于原边权。

然后从刚才加的s->t分割出来的两面对应的两个点跑最短路,求出来的就是s到t的最小割。

要特判n==0||m==0的情况

然后我特判的那个点就T了一万次,在抄elijahqi巨佬的代码的时候才发现:

我是这样写的:

...
#define MIN(x,y) (x<y?x:y)
... ....ans=MIN(ans,read())
....

这能不T就有鬼了吧

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<ctime>
#include<set>
#define pa pair<int,int>
#define lowb(x) ((x)&(-(x)))
#define REP(i,n0,n) for(i=n0;i<=n;i++)
#define PER(i,n0,n) for(i=n;i>=n0;i--)
#define MAX(a,b) ((a>b)?a:b)
#define MIN(a,b) ((a<b)?a:b)
#define CLR(a,x) memset(a,x,sizeof(a))
#define rei register int
using namespace std;
const int maxn=;
typedef long long ll; ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} struct Edge{
int a,b,l,ne;
}eg[maxn*maxn*];
int N,M,egh[maxn*maxn*],ect;
int id[maxn][maxn][],pct;
int dis[maxn*maxn*];bool flag[maxn*maxn*];
priority_queue<pa,vector<pa>,greater<pa> > q; inline void adeg(int a,int b,int l){
eg[ect].a=a;eg[ect].b=b;eg[ect].l=l;
eg[ect].ne=egh[a];egh[a]=ect++;
}
inline void adeg2(int a,int b,int c){adeg(a,b,c);adeg(b,a,c);} inline int dijkstra(int S,int E){
CLR(dis,);dis[S]=;
q.push(make_pair(,S));
while(!q.empty()){
int p=q.top().second;q.pop();
if(p==E) break;
if(flag[p]) continue;
for(rei i=egh[p];i!=-;i=eg[i].ne){
rei b=eg[i].b;
if(dis[b]>dis[p]+eg[i].l){
dis[b]=dis[p]+eg[i].l;
q.push(make_pair(dis[b],b));
}
}flag[p]=;
}return dis[E];
} int main(){
//freopen(".in","r",stdin);
rei i,j,k;
N=rd(),M=rd(); if(N==||M==){
if(N<M) swap(N,M);int ans=0x3f3f3f3f;
REP(i,,N-) ans=min(ans,(int)rd());printf("%d\n",ans);
return ;
}
CLR(egh,-);
id[][][]=++pct;id[][][]=++pct;
REP(i,,N-) REP(j,,M-) id[i][j][]=++pct,id[i][j][]=++pct;
REP(i,,N){
REP(j,,M-){
if(i==) adeg2(id[][j][],id[][][],rd());
else if(i==N) adeg2(id[N-][j][],id[][][],rd());
else adeg2(id[i-][j][],id[i][j][],rd());
}
}
REP(i,,N-){
REP(j,,M){
if(j==) adeg2(id[i][][],id[][][],rd());
else if(j==M) adeg2(id[i][M-][],id[][][],rd());
else adeg2(id[i][j-][],id[i][j][],rd());
}
}
REP(i,,N-){
REP(j,,M-){
adeg2(id[i][j][],id[i][j][],rd());
}
}
printf("%d\n",dijkstra(id[][][],id[][][])); return ;
}