累了就要写题解,近期总是被虐到没脾气。

来回最短路问题貌似也能够用DP来搞。只是拿费用流还是非常方便的。

能够转化成求满流为2 的最小花费。一般做法为拆点,对于 i 拆为2*i 和 2*i+1。然后连一条流量为1(花费依据题意来定) 的边来控制每一个点仅仅能通过一次。

额外加入source和sink来控制满流为2。

代码都雷同,以HDU3376为例。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map> #pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define INF 0x3f3f3f3f
#define Mod 6000007 using namespace std; const int EDGE = 6000000,POINT = 730000; struct E
{
int Max,cost,v,next;
}edge[EDGE]; int head[POINT]; int Top; void Link(int u,int v,int w,int cost)
{
edge[Top].v = v;
edge[Top].Max = w;
edge[Top].cost = cost;
edge[Top].next = head[u];
head[u] = Top++;
} int Map[610][610]; int dis[POINT],cur[POINT],flow[POINT];
bool mark[POINT]; void Updata(int site,int flow,int &cost)
{
for(;cur[site] != -1; site = edge[cur[site]^1].v)
{
edge[cur[site]].Max -= flow;
edge[cur[site]^1].Max += flow;
cost += edge[cur[site]].cost * flow;
}
} queue<int> q; int spfa(int S,int T,int &cost)
{
memset(mark,false,sizeof(mark));
memset(dis,INF,sizeof(dis)); cur[S] = -1,dis[S] = 0,flow[S] = INF; q.push(S); int f,t; while(q.empty() == false)
{
f = q.front();
q.pop();
mark[f] = false; for(int p = head[f];p != -1; p = edge[p].next)
{
t = edge[p].v;
if(edge[p].Max && dis[t] > dis[f] + edge[p].cost)
{
dis[t] = dis[f] + edge[p].cost;
cur[t] = p;
flow[t] = min(flow[f],edge[p].Max); if(mark[t] == false)
{
mark[t] = true;
q.push(t);
}
}
}
} if(dis[T] == INF)
return 0;
Updata(T,flow[T],cost);
return flow[T];
} int Cal_Max_Flow_Min_Cost(int S,int T,int n)
{
int temp,flow = 0,cost = 0; do
{
temp = spfa(S,T,cost);
flow += temp;
}while(temp);
return cost;
} inline int Cal(int x,int y,int n)
{
return ((x-1)*n+y)*2-1;
} int main()
{
int n;
int i,j; while(scanf("%d",&n) != EOF)
{
memset(head,-1,sizeof(head));
Top = 0; for(i = 1;i <= n; ++i)
{
for(j = 1;j <= n; ++j)
{
scanf("%d",&Map[i][j]);
if(i == j && (i == 1 || i == n))
Link(Cal(i,j,n),Cal(i,j,n)+1,2,-Map[i][j]);
else
Link(Cal(i,j,n),Cal(i,j,n)+1,1,-Map[i][j]);
Link(Cal(i,j,n)+1,Cal(i,j,n),0,Map[i][j]);
}
} for(i = 1;i <= n; ++i)
{
for(j = 1;j <= n; ++j)
{
if(j < n)
{
Link(Cal(i,j,n)+1,Cal(i,j+1,n),1,0);
Link(Cal(i,j+1,n),Cal(i,j,n)+1,0,0);
}
if(i < n)
{
Link(Cal(i,j,n)+1,Cal(i+1,j,n),1,0);
Link(Cal(i+1,j,n),Cal(i,j,n)+1,0,0);
}
}
} printf("%d\n",-Cal_Max_Flow_Min_Cost(1,n*n*2,n*n*2) - Map[1][1] - Map[n][n]);
}
return 0;
}

最新文章

  1. 准循环LDPC码用于公钥密码时的奇偶校验矩阵
  2. python的路径
  3. js 验证用户名和密码是否为空
  4. Package Control Installation
  5. zabbix的配置使用
  6. nodejs 相关
  7. 模板-高精度BigInteger
  8. 【python cookbook】【数据结构与算法】4.找到最大或最小的N个元素
  9. 二模 (13)day1
  10. 上次遗留下来的XMLUtil的问题
  11. Windows 2003 AD升级Windows 2008
  12. Page 63-64 Exercises 2.3.7 -------Introduction to Software Testing (Paul Ammann and Jeff Offutt)
  13. 线段树---HDU1166敌兵布阵
  14. 2014年2月5日 Oracle ORACLE的工作机制[转]
  15. STM32关于优先级设定的理解 NVIC_SetPriority()
  16. Asp.net MVC4 CodeFirst 使用EFTracingProvider
  17. apache 基本vhost配置
  18. VS2013 百度云资源以及密钥
  19. 踩坑 —— Eclipse MAVEN编译
  20. python 时间模块 -- time

热门文章

  1. javascript之继承
  2. wpf DataTemplate ColumnDefinition width equal
  3. PHP内置函数实现简单洗牌
  4. django 项目运行时static静态文件不能加载问题处理
  5. 前后端分离之JWT用户认证(转)
  6. Python 项目实践二(生成数据)第二篇
  7. 利用Microsoft Sql Server Management studio 创建数据库的示例
  8. python 字典相关操作
  9. greenDao 介绍
  10. BZOJ2655 calc