您的位置:首页 > 其它

SRM 575 DIV2 博弈P/N分析 + 最大流

2013-04-09 08:34 561 查看
250pt:

题意:

给出一个序列,该序列中可能有相同的值,然后交换任意两个数形成不同序列的数量。

思路:
由于这里的序列长度为n,n <= 1000 所以我们只要利用set的蛆虫特性,O(n^2)枚举swap就可以了。但是如果n非常大达到10^7怎么办?其实我们还可以利用set来记录该序列中一共出现了多少不同的数,只要出现一对不同的数那么交换这两个肯定能够得到一个不同的序列最后结果就是(set.size() - 1)*set.size()/2;

View Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll long long
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);

#define M 272488
#define N 522
using namespace std;

const int inf = 0x7fffffff;

int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};

int level
,q[M];

struct node{
int v,w,u;
int next;
}g[M + 10];

int head
,ct,out
;

void add(int u,int v,int w){
g[ct].v = v;
g[ct].w = w;
g[ct].next = head[u];
head[u] = ct++;

g[ct].v = u;
g[ct].w = 0;
g[ct].next = head[v];
head[v] = ct++;
}
bool layer(int s,int e){
int i;
CL(level,-1);
level[s] = 0;
int l = 0, r= 0;
q[r] = s;
while (l <= r){
int u = q[l++];
for (i = head[u]; i != -1; i = g[i].next){
int v = g[i].v;
if (level[v] == -1 && g[i].w > 0){
level[v] = level[u] + 1;
q[++r] = v;
if (v == e) return true;
}
}
}
return false;
}
int find(int s,int e){
int top = 1,i;
int ans = 0;
while (top){
int u = (top == 1 ? s : g[q[top - 1]].v);
if (u == e){
int MIN = inf ,pos;
for (i = 1; i < top; ++i){
int tp = q[i];
if (g[tp].w < MIN){
MIN = g[tp].w;
pos = i;
}
}
for (i = 1; i < top; ++i){
int tp = q[i];
g[tp].w -= MIN;
g[tp^1].w += MIN;
}
ans += MIN;
top = pos - 1;
}
else{
for (i = head[u]; i != -1; i = g[i].next){
int v = g[i].v;
if (level[v] == level[u] + 1 && g[i].w > 0){
q[top++] = i;
break;
}
}
if (i == -1){
top--;
level[u] = -1;
}
}
}
return ans;
}
int dinic(int s,int e){
int ans = 0;
while (layer(s,e))  ans += find(s,e);
return ans;
}

class TheTilesDivTwo
{
public:
int n,m;
int idx(int i,int j,char a)
{
int as = i*m + j;
return a? as: as + n*m;
}

int find(vector <string> bd)
{
int i,j,k;
n = bd.size();
m = bd[0].size();
CL(head,-1); ct = 0;
if (n < 2) return 0;
if (m < 2) return 0;
int s = 2*n*m,e = 2*n*m + 1;

for (i = 0; i < n; ++i)
{
for (j = 0; j < m; ++j)
{
add(idx(i,j,1),idx(i,j,0),1);
}
}
for (i = 0; i < n; ++i)
{
for (j = 0; j < m; ++j)
{

if ((i + j)%2 == 1 && bd[i][j] != 'X')
{
if (i%2 == 0) add(s,idx(i,j,1),1);
else add(idx(i,j,0),e,1);

for (k = 0; k < 4; ++k)
{
int tx = i + dx[k];
int ty = j + dy[k];
if (tx >= 0 && tx < n && ty >= 0 && ty < m && bd[tx][ty] != 'X')
{
if (i%2 == 0)
add(idx(i,j,1),idx(tx,ty,1),1);
else
add(idx(tx,ty,0),idx(i,j,1),1);
}
}

}
}
}
//            printf(">>>>>>>>>>>\n");
int ans = dinic(s,e);
return ans;
}

};

// Powered by FileEdit
// Powered by TZTester 1.01 [25-Feb-2003]
// Powered by CodeProcessor

// Powered by FileEdit
// Powered by TZTester 1.01 [25-Feb-2003]
// Powered by CodeProcessor
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: