平面图->对偶图


平面图

若对于一个在平面上的图 \(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