P2764 最小路径覆盖问题

dinic


int bfs() {
    queue<int> q;
    fill(d, d + maxn, 0);
    d[s] = 1;
    q.push(s);
    while(!q.empty()) {
        int x = q.front();
        q.pop();
        for(int i = G[x].size() - 1 ; i >= 0 ; i -- ){
			edge& e = edges[G[x][i]];
            if(!d[e.to] && e.val > 0) {
                d[e.to] = d[e.from] + 1;
                q.push(e.to);
            }
        }
    }
    
    return d[t] > 0;
}


int dfs(int u, long long flow) {
    if(u == t)
        return flow;
    int from = u;
    
	for(int i = G[from].size() - 1 ; i >=0 ; i-- ){
		edge& e = edges[G[from][i]];
		int v = e.to;
        if(d[v] == d[u] + 1 && e.val > 0) {
            int res = dfs(v, min(flow, e.val));
            if(res > 0) {
                e.val -= res;
                edges[G[from][i]^1].val += res;
                if(u != s && v != t)
                    nxt[u] = v;
                if(u != s && v > n)
                    tag[v - n] = 1;
                return res;
            }
        }
    }
    return 0;
}	


int dinic() {
    int res = 0;
    while(bfs()) {
        while(int d = dfs(s, inf))
            res += d;
    }
    for(int i = 1; i <= n; i++) {
        if(!tag[i]) {
            int u = i;
            printf("%d ", u);
            while(nxt[u] && nxt[u] != t) {
                printf("%d ", nxt[u] - n);
                u = nxt[u] - n;
            }
            cout <<"\n";
        }
    }
    return res;
}


ISAP

void bfs(){
	
	
	fill(d, d + maxn, -1);
	fill(gap, gap + maxn, 0);
	
	d[t] = 0;
	gap[d[t]] ++ ;
	
	queue<int> q;
	q.push(t);
	
	while(!q.empty()){
		int x = q.front();
		q.pop();
		
		for(int i = G[x].size() - 1 ; i >= 0 ; i -- ){
			edge& e = edges[G[x][i]^1];
			if(d[e.from] < 0){
				d[e.from] = d[e.to] + 1;
				gap[d[e.from]] ++;
				q.push(e.from);
			}
		}
	}
	return;
}

long long dfs(int to, long long flow){
	if(to == t){
		max_flow += flow;
		return flow;
	}
	long long used = 0;
	for(int i = G[to].size() - 1; i >=0  ;i-- ){
		edge& e = edges[G[to][i]];
		if(e.val > 0 && d[e.from] == d[e.to] + 1){
			long long mi = dfs(e.to, min(e.val, flow - used));
			if(mi){ // can be flowed out! 
				e.val -= mi;
				edges[G[to][i]^1].val += mi;
				used += mi;
				
				if(e.from != s && e.to != t){
					nxt[e.from] = e.to;
				}
				if(e.to != t && e.to > n)
	                tag[e.to - n] = 1;
			}

                
			if(used == flow)
				return used;
		}	
	}
	gap[d[to]]--;
	if(gap[d[to]] == 0)
		d[1] = t + 1;
		
	gap[++d[to]] ++;
	return used;
}


long long ISAP(int s){
	max_flow = 0;
	
	bfs();
	
	while(d[s] < t){
		dfs(s, inf);
		//printf("%d \n", max_flow);
		
	}
	
	
	for(int i = 1; i <= n; i++) {
        if(!tag[i]) {
            int u = i;
            printf("%d ", u);
            while(nxt[u] && nxt[u] != t) {
                printf("%d ", nxt[u] - n);
                u = nxt[u] - n;
            }
            cout << "\n";//puts("");
        }
    }

	return max_flow;
	
}

HELLO WORLD

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

using namespace std;

int n, m;
int s, t;

struct edge{
	int from, to;
	long long val;
	int cost;
	edge(int f, int t, int v, int c = 1):from(f), to(t), val(v){
		cost = c;
	}
};

const int maxn = 200 * 2;

vector<edge> edges;
vector<int> G[maxn];

void addEdge(int from, int to, int val){
	edges.push_back(edge(from, to, val, 1));
	edges.push_back(edge(to, from, 0, -1));
	int m = edges.size();
	G[from].push_back(m - 2);
	G[to].push_back(m - 1);
	return;
}

int pre[maxn];
long long  flow[maxn];
int inq[maxn];
int d[maxn];

// for retracing the path
int nxt[maxn], tag[maxn];

const int inf = 1 << 30;

bool spfa(){
	
	fill(flow, flow + maxn, inf);
	fill(inq, inq + maxn, 0);
	fill(d, d + maxn, inf);
	
	queue<int> q;
	q.push(s);
	
	inq[s] = 1;
	d[s] = 0;
	
	while(!q.empty()){
		
		int from = q.front(); q.pop();
		inq[from] = 0;
		
		for(int i = G[from].size() - 1 ; i >= 0 ; i-- ){
			int to_index = G[from][i];
			edge& e = edges[to_index];
			
			if(e.val > 0 && d[e.from] + e.cost < d[e.to]){
				// for traceback
				pre[e.to] = to_index;
				flow[e.to] = min(flow[e.from], e.val);
				d[e.to] = d[e.from] + e.cost;
				
				if(!inq[e.to]){
					q.push(e.to);
					inq[e.to] = 1;
				}

			}
		}
	}
	return d[t]!=inf;;
		
}




void update(int& max_flow){
	int cur = t;
	int delta = flow[t];
	
	while(cur != s){
		// from t to s
		int index = pre[cur];
		edges[index].val -= delta;
		edges[index^1].val += delta;
		cur = edges[index^1].to;
		
		// for last output 
		edge& e = edges[index];
		if(e.from != s && e.to != t){
			nxt[e.from] = e.to;
		}
		// if tagged <=> be tranversed <=> can't be the starting points
		if(e.to != t && e.to > n)
	        tag[e.to - n] = 1;
	}
	max_flow += delta;
}

void EK(int& max_flow){
	while(spfa()){
		update(max_flow);
	}
	// for output
	for(int i = 1; i <= n; i++) {
		// find the start points
        if(!tag[i]) {
            int u = i;
            printf("%d ", u);
            // lets go ~
            while(nxt[u] && nxt[u] != t) {
                printf("%d ", nxt[u] - n);
                u = nxt[u] - n;
            }
            cout << "\n";
        }
    }	
	
}

int max_flow = 0;

int main(int argc, char** argv) {
	freopen("1.txt", "r", stdin);
	cin >> n >> m ;
	s = n * 2 + 1;
	t =  n * 2 + 2;
	
	for(int i = 1 ; i <= n ; i ++ ){
		 addEdge(s, i, 1);
		 addEdge(i + n, t, 1);
	}	 
	
	for(int i = 0 ; i < m ; i ++ ){
		int from, to;
		cin >> from >> to;
		addEdge(from, to + n, 1);
	}

	EK(max_flow);

	cout << n - max_flow << endl;
	
	
	return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值