1 条题解
-
0
C++ :
#include <cstdio> #include <cstring> #include <algorithm> #define INF 0x1f1f1f1f #define MAXV 600 #define MAXE 5000 using namespace std; int flag[MAXV], head[MAXV], size, edgeID[MAXE]; int que[MAXV + 10], front, rear, pre[MAXV]; int dist[MAXV], maxFlow[MAXV]; struct Edge { int v, next, opp; //边上的另一个顶点, 下一条边, 反向边 int cost, cap, f; //花费、容量、流量 Edge(){} Edge(int _v, int _cost, int _cap, int _f, int _next, int _opp): v(_v), cost(_cost), cap(_cap), f(_f), next(_next), opp(_opp){} }edge[MAXE]; void init() { size = 0; memset(head, -1, sizeof(head)); } void add_edge(int u, int v, int cap, int cost, int f = 0) { edge[size] = Edge(v, cost, cap, f, head[u], size + 1); edgeID[size] = u; head[u] = size++; edge[size] = Edge(u, -cost, 0, f, head[v], size - 1); edgeID[size] = v; head[v] = size++; } int SPFA(int S, int T) { //找花费最小的一条路 int i, u, v; front = rear = 0; memset(flag, 0, sizeof(flag)); memset(dist, 0x1f, sizeof(dist)); memset(pre, -1, sizeof(pre)); dist[S] = 0; flag[S] = 1; maxFlow[S] = INF; que[rear++] = S; while (front != rear) { u = que[front++]; if(front >= MAXV) front = 0; flag[u] = 0; for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if (edge[i].cap > edge[i].f && dist[v] > dist[u] + edge[i].cost){ dist[v] = dist[u] + edge[i].cost; maxFlow[v] = min(edge[i].cap - edge[i].f, maxFlow[u]); pre[v] = i; //记录前驱在edge中的下标 if (!flag[v]) { que[rear++] = v; if (rear >= MAXV) rear = 0; flag[v] = 1; } } } } if (dist[T] == INF) return 0; else return 1; } int MFMC(int S, int T) { int sumCost, sumFlow, k; sumCost = sumFlow = 0; while (SPFA(S, T)) { k= T; while (pre[k] >= 0) { edge[pre[k]].f += maxFlow[T]; edge[edge[pre[k]].opp].f = -edge[pre[k]].f; k = edgeID[pre[k]]; } sumFlow += maxFlow[T]; sumCost += dist[T] * maxFlow[T]; } return sumCost; } char board[16][16]; int main() { init(); int r, c, n, src, sink; scanf("%d%d",&r,&c); for(int i = 0;i < r; ++i) scanf("%s",board[i]); const char D[] = "ULDR"; const int dx[] = {0, -1, 0, 1}; const int dy[] = {-1, 0, 1, 0}; n = r * c; src = 2*n; sink = 2*n + 1; for(int i = 0;i < n; ++i){ add_edge(src, i, 1, 0); add_edge(i + n, sink, 1, 0); } for(int x = 0;x < c; ++x){ for(int y = 0;y < r; ++y){ for(int d = 0;d < 4; ++d){ int nx = (x + dx[d] + c) % c; int ny = (y + dy[d] + r) % r; if(board[y][x] == D[d]){ add_edge((y*c+x), ny*c+nx+n, 1, 0); }else{ add_edge((y*c+x), ny*c+nx+n, 1, 1); } } } } printf("%d\n",MFMC(src, sink)); }
- 1
信息
- ID
- 1027
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者