您的位置:首页 > 其它

HDU-3870-Catch the Theves

2016-12-12 14:19 591 查看
ACM模版

描述





题解

用最小割做是要死人的,看了周冬前辈中学时的论文,搞清楚了这种题要转化为最短路搞,不过建起图来是一个恶心人的事情~~~



具体论文参见:浅析最大最小定理在信息学竞赛中的应用

代码

#include <iostream>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

const int MAXN = 170000;
const int INF = 0x3f3f3f3f;

struct point
{
int v, w;
} Point;

vector<point> Edge[MAXN];

int n,S,T,q[MAXN];
int dist[MAXN];
bool inq[MAXN];

int SPFA()
{
int head = 0, tail = 0;
memset(inq, false, sizeof(inq));

for (int i = 0; i <= (n - 1) * (n - 1) + 1; i++)
{
dist[i] = INF;
}

q[tail++] = S;
dist[S] = 0;
inq[S] = true;

while (head != tail)
{
int k = q[head];
head = (head + 1) % MAXN;
inq[k] = false;
for (int i = 0; i < Edge[k].size(); i++)
{
Point = Edge[k][i];
if (dist[Point.v] > dist[k] + Point.w)
{
dist[Point.v] = dist[k] + Point.w;
if (!inq[Point.v])
{
inq[Point.v] = true;
q[tail] = Point.v;
tail = (tail + 1) % MAXN;
}
}
}
}
return dist[T];
}

int main()
{
int t;
scanf("%d", &t);

while (t--)
{
scanf("%d", &n);
for (int i = 0; i < (n - 1) * (n - 1) + 2; i++)
{
Edge[i].clear();
}
S = (n - 1) * (n - 1);
T = (n - 1) * (n - 1) + 1;

int w;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
scanf("%d", &w);
Point.w = w;
if (i == 0 && j != n - 1)
{
Point.v = j;
Edge[S].push_back(Point);
}
else if (j == n - 1 && i != n - 1)
{
Point.v = i * (n - 1) + j - 1;
Edge[S].push_back(Point);
}

if (j == 0 && i != n - 1)
{
Point.v = T;
Edge[i * (n - 1)].push_back(Point);
}
else if (i == n - 1 && j != n - 1)
{
Point.v = T;
Edge[(n - 2) * (n - 1) + j].push_back(Point);
}

if (i != n - 1 && j != n - 1)
{
if (i)
{
Point.v = (i - 1) * (n - 1) + j;
Edge[i * (n - 1) + j].push_back(Point);
Point.v = i * (n - 1) + j;
Edge[(i - 1) * (n - 1) + j].push_back(Point);
}
if (j)
{
Point.v = i * (n - 1) + j - 1;
Edge[i * (n - 1) + j].push_back(Point);
Point.v = i * (n - 1) + j;
Edge[i * (n - 1) + j - 1].push_back(Point);
}
}
}
}

printf("%d\n", SPFA());
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最小割 最短路