1 条题解

  • 0
    @ 2021-6-15 14:36:42

    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
    上传者