平面图->对偶图
平面图
若对于一个在平面上的图 \(G\) ,有 \(\forall u,v\in G\),其交点为 \(G\) 顶点,则称这个图为平面图。
对偶图
在原图的边隔开的每个面上选一个点,若两个点相连穿过且仅穿过一条边就将它俩连起来,这条边的边权即为原图被穿过的边的边权
\(↑\)懒得画图也不太会用人类语言描述,感性理解(
因为可以将对偶图的边权看作删除原图的边的代价,所以对偶图上的最短路就是原图最小割
对偶图建图是怎么回事呢?对偶图相信大家都很熟悉,但是对偶图建图是怎么回事呢,下面就让我们一起了解吧。
对偶图建图,其实就是将平面图转换为对偶图,大家可能会很惊讶对偶图怎么会建图呢?但事实就是这样,我也感到非常惊讶。
这就是关于对偶图建图的事情了,大家有什么想法呢。
//4001
#include
using namespace std;
long long read()
{
long long res=0,p=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-')p=-1; ch=getchar();}
while(isdigit(ch)) res=res*10+ch-'0',ch=getchar();
return res*p;
}
const int maxn=2010,inf=0x3f3f3f3f;
int n,m,sumn;
long long ans;
int line[maxn][maxn],cur[maxn][maxn],row[maxn][maxn];
long long dis[maxn*maxn*2];
bool vis[maxn*maxn*2];
int s,t;
int head[maxn*maxn*2],cnt;
struct note
{
int nxt,to,val;
}ed[maxn*maxn*4];
void add(int u,int v,int w)
{
ed[++cnt].nxt=head[u],ed[cnt].to=v,ed[cnt].val=w,head[u]=cnt;
}
int id(int x,int y,int flag)
{
if(((x-1)*m+y)*2+flag==t) cout< q;
void dij()
{
q.push((node){s,0}),memset(dis,0x3f,sizeof(dis)),dis[s]=0;
while(!q.empty())
{
node now=q.top();q.pop();
int u=now.pos;
if(vis[u]) continue ;
vis[u]=1;
for(int i=head[u];i;i=ed[i].nxt)
{
int v=ed[i].to,w=ed[i].val;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!vis[v]) q.push((node){v,dis[v]});
}
}
}
}
int main()
{
n=read(),m=read(),sumn=(n-1)*(m-1)*2,s=0,t=n*m*2+1;
if(n==1||m==1)
{
n=max(n,m),ans=inf;
for(int i=1;i<=n;++i) ans=min(ans,read());
cout<1) add(id(i,j,0),id(i-1,j,1),line[i][j]);
if(j1) add(id(i,j,1),id(i,j-1,0),row[i][j]);
if(i