网络流求助
查看原帖
网络流求助
667448
go_deeper楼主2023/11/17 11:37
//I'm sorry.
//No,it's too late to say it.
//This is where friendship collapse.
//If you like me,it's never to be late.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define notall(x) x.begin()+1,x.end()
#define all(x) x.begin(),x.end()
#define mul_t int _t;cin>>_t;while(_t--)
const int int_inf = 1000000100;
const ll ll_inf = 1000000000000000100;
//writers
template<class T>
void writeln(const T &t) {
    cout << t << '\n';
}
template<class T, class...args>
void writeln(const T &t, const args &...rest) {
    cout << t << ' ';
    writeln(rest...);
}
template<class T1>
void writeln(const vector<T1> &v) {
    for (auto c : v)
        cout << c << ' ';
    cout << ' ' << '\n';
}
template<class T1, class T2>
void writeln(const vector<T1> &v, T2 n) {
    for (T2 i = 1; i <= n; i++)
        cout << v[i] << ' ';
    cout << ' ' << '\n';
}
template<class T1, class T2>
void writeln(const pair<T1, T2> p) {
    cout << p.first << ' ' << p.second << ' ' << '\n';
}

struct DinicGraph {
	struct Edge {
		int v, rev;
		long long cap, flow;
		Edge(int v, long long cap, int rev) : v(v), cap(cap), flow(0), rev(rev) {}
	};
	int n;
	std::vector<std::vector<Edge>> graph;
	std::vector<int> level, iter;
	bool bfs(int source, int sink) {
		level.assign(n, -1);
		std::queue<int> q;
		level[source] = 0;
		q.push(source);
		while (!q.empty()) {
			int u = q.front();
			q.pop();
			for (const Edge& e : graph[u]) {
				if (level[e.v] < 0 && e.flow < e.cap) {
					level[e.v] = level[u] + 1;
					q.push(e.v);
				}
			}
		}
		return level[sink] >= 0;
	}
	long long dfs(int u, int sink, long long path_flow) {
		if (u == sink)
			return path_flow;
		for (int& i = iter[u]; i < graph[u].size(); ++i) {
			Edge& e = graph[u][i];
			if (level[u] + 1 == level[e.v] && e.flow < e.cap) {
				long long augment = dfs(e.v, sink, std::min(path_flow, e.cap - e.flow));
				if (augment > 0) {
					e.flow += augment;
					graph[e.v][e.rev].flow -= augment;
					return augment;
				}
			}
		}
		return 0;
	}
	DinicGraph(int n) : n(n), graph(n), level(n), iter(n) {}
	void addEdge(int u, int v, long long cap) {
		graph[u].emplace_back(v, cap, graph[v].size());
		graph[v].emplace_back(u, 0, graph[u].size() - 1);
	}
	long long maxFlow(int source, int sink) {
		long long max_flow = 0;
		while (bfs(source, sink)) {
			iter.assign(n, 0);
			long long path_flow;
			while ((path_flow = dfs(source, sink, std::numeric_limits<long long>::max())) > 0) {
				max_flow += path_flow;
			}
		}
		return max_flow;
	}
};

//DSU
struct dsu {
	vector<int>fa;
	vector<ll> val,siz;
	dsu(int n) {
		fa.resize(n + 1), siz.resize(n + 1), val.resize(n+1);
		for (int i = 1; i <= n; i++)
			fa[i] = i, siz[i] = 1;
	}
	int ffind(int x) {
		if(x!=fa[x]) {
			int pa=fa[x];
			fa[x]=ffind(fa[x]);
			val[x]+=val[pa];
		}
		return fa[x];
	}
	bool uuion(int x, int y , ll z=0) {
		int px = ffind(x), py = ffind(y);
		if (px == py)
			return false;
		fa[py] = px, siz[px] += siz[py], siz[py] = 0,val[py] = -val[y] + val[x] + z;
		return true;
	}
	bool check(int x, int y) {
		return ffind(x) == ffind(y);
	}
	int check(int x,int y,ll z) {
		if(!check(x,y))return -1;
		return val[x] + z == val[y];
	}
	void init() {
		for (size_t i = 1; i <= fa.size() - 1; i++)
			fa[i] = i, siz[i] = 1, val[i] = 0;
	}
	int getsize(int x) {
		return siz[x];
	}
};

void solve(){
    int n,m,k;
    cin>>n>>m>>k;
    vector<vector<int>>s(m+1);
    vector<int>h(m+1);
    dsu d(n+1);
    for(int i=1;i<=m;i++)
    {
        int r,lst=-1;
        cin>>h[i]>>r;
        s[i].resize(r);
        for(auto&c:s[i])
        {
            cin>>c;
            ++c;
            if(~lst)d.uuion(c,lst);
            lst=c;
        }
    }
    if(!d.check(0,1))
    {
        writeln(0);
        return;
    }
    DinicGraph e(114514);
    e.addEdge(100000,1,int_inf);
    cout<<100000<<' '<<1<<' '<<int_inf<<endl;
    for(int i=1;i<=1000;i++)
    {
        for(int j=0;j<=n+1;j++)
        {
            e.addEdge((i-1)*(n+2)+j,i*(n+2)+j,int_inf);
            cout<<(i-1)*(n+2)+j<<' '<<i*(n+2)+j<<' '<<int_inf<<endl;
        }
        for(int j=1;j<=m;j++)
        {
            int sz=s[j].size();
            int lst=(i-1)%sz,now=i%sz;
            cout<<(i-1)*(n+2)+s[j][lst]<<' '<<i*(n+2)+s[j][now]<<' '<<h[j]<<endl;
            e.addEdge((i-1)*(n+2)+s[j][lst],i*(n+2)+s[j][now],h[j]);
        }
        e.addEdge(i*(n+2),100001,int_inf);
        cout<<i*(n+2)<<' '<<100001<<' '<<int_inf<<endl;
        if(e.maxFlow(100000,100001)>=k)
        {
            writeln(i);
            break;
        }
    }
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << fixed << setprecision(15);
    //mul_t
    solve();
}
/*
1.深呼吸,不要紧张,慢慢读题,读明白题,题目往往比你想的简单。
2.暴力枚举:枚举什么,是否可以使用一些技巧加快枚举速度(预处理、前缀和、数据结构、数论分块)。
3.贪心:需要排序或使用数据结构(pq)吗,这么贪心一定最优吗。
4.二分:满足单调性吗,怎么二分,如何确定二分函数返回值是什么。
5.位运算:按位贪心,还是与位运算本身的性质有关。
6.数学题:和最大公因数、质因子、取模是否有关。
7.dp:怎么设计状态,状态转移方程是什么,初态是什么,使用循环还是记搜转移。
8.搜索:dfs 还是 bfs ,搜索的时候状态是什么,需要记忆化吗。
9.树上问题:是树形dp、树上贪心、或者是在树上搜索。
10.图论:依靠什么样的关系建图,是求环统计结果还是最短路。
11.组合数学:有几种值,每种值如何被组成,容斥关系是什么。
12.交互题:log(n)次如何二分,2*n 次如何通过 n 次求出一些值,再根据剩余次数求答案。
13.如果以上几种都不是,多半是有一个 point 你没有注意到,记住正难则反。
*/

感觉建图是对的,但是跑出来的最大流的值有问题

2023/11/17 11:37
加载中...