题意:有F种食物 D种饮料 它们都有一定的数量 有N个人 每个人都有自己喜欢吃的食物和饮料 (每个人至少要一种食物和饮料) 只有能满足他的要求时他才会接服务 求最大能满足多少人?
char str[300] ; int main(){ int N , m , i , j , u , v , c , F , D ; while(scanf("%d%d%d" ,&N ,&F , &D) != EOF){ init() ; sourse = 0 ; meet = F + 2*N + D + 1 ; for(i = 1 ; i <= F ; i++){ scanf("%d" ,&c) ; add(sourse , i , c) ; } for(i = 1 ; i <= D ; i++){ scanf("%d" ,&c) ; add(F + 2*N+ i , meet , c) ; } for(i = 1 ; i <= N ; i++) add(F+i , F+N+i , 1) ; for(i = 1 ; i <= N ; i++){ scanf("%s" ,str+1) ; for(j = 1 ; j <= F ; j++) if(str[j] == 'Y') add(j , F+i , 1) ; } for(i = 1 ; i <= N ; i++){ scanf("%s" ,str+1) ; for(j = 1 ; j <= D ; j++) if(str[j] == 'Y') add(F+N+i , F+2*N+j , 1) ; } printf("%d\n" , maxflow()) ; } return 0 ; }
题意:有n个城市和m条道路(双向),一伙小偷准备从S城出发到H城盗窃,为了将这伙小偷抓住,需要在这n个城市中的每一个城市安排一定数量的警察(每个城市警察的数量已经给出),但警察不希望在S城或H城遇到小偷.求解总共需要的最少警察数. 这个模型很腻了。
int main(){ int n , m , i , j , u , v , c , sum , s , h , T; cin>>T ; while(T--){ scanf("%d%d%d%d" ,&n ,&m ,&s ,&h) ; init() ; sourse = 0 ; meet = n*2 + 1 ; for(i = 1 ; i <= n ; i++){ scanf("%d" ,&c) ; if(i == s || i == h) add(i , i+n , inf) ; else add(i , i+n , c) ; } for(i = 1 ; i <= m ; i++){ scanf("%d%d" ,&u ,&v) ; add(u+n , v , inf) ; add(v+n , u , inf) ; } add(sourse , s , inf) ; add(h+n , meet , inf) ; printf("%d\n" , maxflow()) ; } return 0 ; }
题意: 有 n 个城市,知道了起点和终点,有 m 条有向边,问从起点到终点不相交的最短路一共有多少条。
解法:其实很好理解,首先每条边能走一次。 那么这条边是最短路上的边,容量为1 。
最大流即为答案。
spfa()一遍即可。如果存在dist[u] + w = dist[v] , 则add(u , v, 1) 。
一般不会卡使用什么方法去求最大流,最好编写的就是好的。
struct Edge2{ int v , w ; Edge2(){} ; Edge2(int _v , int _w):v(_v) , w(_w){} }; vector<Edge2> List[maxn] ; bool in[maxn] ; queue <int>Q ; void spfa(int s , int dist[] , int n){ memset(in , 0 , (n+1) * sizeof(bool)) ; fill(dist, dist+n+1 , inf) ; dist[s] = 0 ; in[s] = 1 ; while(! Q.empty()) Q.pop() ; Q.push(s) ; while(! Q.empty()){ int u = Q.front() ; Q.pop() ; in[u] = 0 ; for(vector<Edge2>::iterator it = List[u].begin() ; it != List[u].end() ; it++){ int v = it->v ; if(dist[u] + it->w < dist[v]){ dist[v] = dist[u] + it->w ; if(! in[v]){ Q.push(v) ; in[v] = 1 ; } } } } } int dist1[maxn] ; int main(){ int n , m , i , j , u , v , s, t , w , T ; cin>>T ; while(T--){ scanf("%d%d" ,&n ,&m) ; for(i = 1 ; i <= n ; i++) List[i].clear() ; for(i = 1 ; i <= m ; i++){ scanf("%d%d%d" ,&u,&v,&w) ; if(u != v) List[u].push_back(Edge2(v , w)) ; } scanf("%d%d" ,&s ,&t) ; spfa(s , dist1 , n) ; if(dist1[t] == inf){puts("0") ; continue ;} init() ; for(u = 1 ; u <= n ; u++){ for(vector<Edge2>::iterator it = List[u].begin() ; it != List[u].end() ; it++){ if(dist1[u] + it->w == dist1[it->v]) add(u , it->v , 1) ; } } sourse = s ; meet = t ; printf("%d\n" , maxflow()) ; } return 0 ; }