圖論:平面圖的對偶圖


平面圖我們離散課上講過,在二維空間中可以寫成不交叉邊的圖就是平面圖,最小的非平面圖有K5和K(3,3)

每個平面圖都對應一個對偶圖,對偶圖中的最小環就是原圖的最小割

如果刪去對偶圖中s-t這條邊,就是相當於求最短路了

把原圖中每個點在對偶圖中標號,重新建圖,在新圖中跑最短路就行了

然后看一下平面圖和對偶圖之間的轉化:

對偶圖中的每一個點即為平面圖中的某一個面,對偶圖中任意兩點間的線都是平面圖中對應兩平面公共邊的割線,如果平面圖中某一條邊只屬於一個面,那么在對偶圖中就是一個環邊

對偶圖的邊數等於平面圖的邊數,對偶圖的點數等於平面圖的面數

 

針對BZOJ1001

①把每一個圖中的面積塊當作新的點。
②每一條邊都與兩個面相連,把面看作點后,這條邊連接這兩個面化作的點,權值不變。
③連接起點與終點,把外面的最大平面分成兩份,分別為最短路的起點與終點。
④跑一邊最短路即可。

我感覺難在建圖上,別的都非常好說

建圖必須好好研究一下

 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=2000005;
 4 int n,m,nm,cnt;
 5 bool vi[maxn];
 6 int dis[maxn],g[maxn],q[maxn];
 7 struct Edge
 8 {
 9     int t,next,w;
10 }e[4*maxn];
11 void insert(int u,int v,int w)
12 {
13     cnt++;e[cnt].t=v;e[cnt].w=w;e[cnt].next=g[u];g[u]=cnt;
14     cnt++;e[cnt].t=u;e[cnt].w=w;e[cnt].next=g[v];g[v]=cnt;
15 }
16 void spfa()
17 {
18     memset(dis,0x3f,sizeof(dis));
19     dis[0]=0;
20     int h=0,t=1;
21     q[t]=0;
22     vi[0]=1;
23     while(h!=t)
24     {
25         h=h%maxn+1;
26         int u=q[h];
27         vi[u]=0;
28         for(int tmp=g[u];tmp;tmp=e[tmp].next)
29         {
30             int v=e[tmp].t;
31             if(dis[v]>dis[u]+e[tmp].w)
32             {
33                 dis[v]=dis[u]+e[tmp].w;
34                 if(!vi[v])
35                 {
36                     t=t%maxn+1;
37                     vi[v]=1;
38                     q[t]=v;
39                 }
40             }
41         }
42     }
43 }
44 int main()
45 {
46     scanf("%d%d",&n,&m);
47     nm=(n*m-m-n+1)<<1;
48     int x;
49     for(int j=1;j<m;j++)
50     {
51         scanf("%d",&x);
52         insert(j,nm+1,x);
53     }
54     for(int i=1;i<n-1;i++)
55     {
56         for(int j=1;j<m;j++)
57         {
58             scanf("%d",&x);
59             insert((i<<1)*(m-1)+j,((i<<1)-1)*(m-1)+j,x);
60         }
61     }
62     for(int j=1;j<m;j++)
63     {
64         scanf("%d",&x);
65         insert(0,((n<<1)-3)*(m-1)+j,x);
66     }
67     for(int i=0;i<n-1;i++)
68     {
69         for(int j=1;j<=m;j++)
70         {
71             scanf("%d",&x);
72             if(j==1) insert(0,(i<<1)*(m-1)+m,x);
73             else if(j==m) insert((i<<1|1)*(m-1),nm+1,x);
74             else insert((i<<1)*(m-1)+j-1,(i<<1)*(m-1)+j+m-1,x);
75         }
76     }
77     for(int i=0;i<n-1;i++)
78     {
79         for(int j=1;j<m;j++)
80         {
81             scanf("%d",&x);
82             insert((i<<1|1)*(m-1)+j,(i<<1)*(m-1)+j,x);
83         }
84     }
85     spfa();
86     printf("%d",dis[nm+1]);
87     return 0;
88 } 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM