zoukankan      html  css  js  c++  java
  • HDU3870 Catch the Theves(平面图最小割转最短路)

    题目大概说给一个n×n的方格,边有权值,问从求(1,1)到(n,n)的最小割。

    点达到了160000个,直接最大流不好。这题的图是平面图,求最小割可以转化成求其对偶图的最短路,来更高效地求解:

    首先源点汇点间新加一条边,然后构造其对偶图:

    • 面作为对偶图的点;而源点到汇点之间新加的边划分出来的两个面分别作为对偶图的源点和汇点
    • 如果两个面之间有边则两个面在对偶图对应的点连边,权值为原来的边权;去掉对偶图源点和汇点之间边

    这样可以发现,对偶图的源点到汇点的一条路径就对应这原图的源点到汇点的一个割边集,而最短路就对应最小割了。所以求一下最小割就OK了,我用SPFA好像超时了,改用堆优化的Dijkstra,10W个点OK。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 #define INF (1<<30)
     7 #define MAXN 1111*1111
     8 struct Edge{
     9     int v,w,next;
    10 }edge[MAXN<<1];
    11 int vs,vt,NV,NE,head[MAXN];
    12 void addEdge(int u,int v,int w){
    13     edge[NE].v=v; edge[NE].w=w; edge[NE].next=head[u];
    14     head[u]=NE++;
    15 }
    16 struct Node{
    17     int u,d;
    18     Node(int _u=0,int _d=0):u(_u),d(_d){}
    19     bool operator<(const Node &nd)const{
    20         return nd.d<d;
    21     }
    22 };
    23 int d[MAXN];
    24 bool vis[MAXN];
    25 int dijkstra(){
    26     for(int i=0; i<NV; ++i){
    27         d[i]=INF; vis[i]=0;
    28     }
    29     d[vs]=0;
    30     priority_queue<Node> que;
    31     que.push(Node(vs,0));
    32     while(!que.empty()){
    33         Node nd=que.top(); que.pop();
    34         if(nd.u==vt) return nd.d;
    35         if(vis[nd.u]) continue;
    36         vis[nd.u]=1;
    37         for(int i=head[nd.u]; i!=-1; i=edge[i].next){
    38             int v=edge[i].v;
    39             if(vis[v]) continue;
    40             if(d[v]>d[nd.u]+edge[i].w){
    41                 d[v]=d[nd.u]+edge[i].w;
    42                 que.push(Node(v,d[v]));
    43             }
    44         }
    45     }
    46     return INF;
    47 }
    48 int a[444][444];
    49 int main(){
    50     int t,n;
    51     scanf("%d",&t);
    52     while(t--){
    53         scanf("%d",&n);
    54         if(n==1){
    55             puts("0");
    56             continue;
    57         }
    58         vs=(n-1)*(n-1); vt=vs+1; NV=vt+1; NE=0;
    59         memset(head,-1,sizeof(head));
    60         for(int i=0; i<n; ++i){
    61             for(int j=0; j<n; ++j){
    62                 scanf("%d",&a[i][j]);
    63             }
    64         }
    65         for(int i=0; i<n-1; ++i){
    66             for(int j=0; j<n; ++j){
    67                 if(j==0){
    68                     addEdge(vs,i*(n-1)+j,a[i][j]);
    69                 }else if(j==n-1){
    70                     addEdge(i*(n-1)+j-1,vt,a[i][j]);
    71                 }else{
    72                     addEdge(i*(n-1)+j,i*(n-1)+j-1,a[i][j]);
    73                     addEdge(i*(n-1)+j-1,i*(n-1)+j,a[i][j]);
    74                 }
    75             }
    76         }
    77         for(int j=0; j<n-1; ++j){
    78             for(int i=0; i<n; ++i){
    79                 if(i==0){
    80                     addEdge(i*(n-1)+j,vt,a[i][j]);
    81                 }else if(i==n-1){
    82                     addEdge(vs,(i-1)*(n-1)+j,a[i][j]);
    83                 }else{
    84                     addEdge(i*(n-1)+j,(i-1)*(n-1)+j,a[i][j]);
    85                     addEdge((i-1)*(n-1)+j,i*(n-1)+j,a[i][j]);
    86                 }
    87             }
    88         }
    89         printf("%d
    ",dijkstra());
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    Web Service测试工具小汇
    Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
    Android--消除“Permission is only granted to system apps”错误
    android设置gps自动开启
    Android中实现日期时间选择器(DatePicker和TimePicker)
    android在点击EditText的时候始终不弹出软件键盘
    Android检测服务是否运行
    Android检测网络状态,判断当前网络是否可用
    wap测试学习
    【转】十二个移动App云测试服务盘点
  • 原文地址:https://www.cnblogs.com/WABoss/p/5455721.html
Copyright © 2011-2022 走看看