Regionals >> Asia-tehran >> 7530-cafebazaar
Topic Links: 7530
A company has n developers, there is a M app can be developed. Some of these developers must choose, some apps are required. Each developer is known to develop the benefits of each app to maximize revenue. (Each developer develops a maximum of one app, one per app at most)
Topic Ideas:
Solution 1:2 Graph Best match (km algorithm)
Add some virtual developers and virtual apps, non-essential apps can be developed by virtual developers, the revenue is 0, in turn, non-essential developers can develop virtual apps, the revenue is 0. Virtual developers can then also develop virtual apps, with a profit of 0, which allows the KM to meet the composition conditions.
Note: The necessary developers and their corresponding non-developer apps are set directly to a negative INF2 value, so that they have an edge between them but if you really want to choose this side, the final answer is definitely negative. That is, there is no viable solution. The necessary apps and their corresponding developers
setting of the weight value:
if (存在一个重要的app)边权值加INFif (存在一个重要的开发者)边权值加INF//最多可加两个INF
Then you can apply the template.
Here's the code:
#include <iostream>#include <iomanip>#include <fstream>#include <sstream>#include <cmath>#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>#include <functional>#include <numeric>#include <string>#include <set>#include <map>#include <stack>#include <vector>#include <queue>#include <deque>#include <list>using namespace STD;#define LL Long Long#define MOD 1000000000Const intN = the;Constll INF =100000000000000LLConstll INF2 =1000000000000LLintNx,ny;//Side points NX, number of first team, NY, number of second team. Note that NX <= NY, otherwise it will die loop. ll G[n][n];//Two description g[i][j],i belongs to the first team, J belongs to the second team. ll Linker[n],lx[n],ly[n];Point Matching status in//y, Dot label in X, yll Slack[n];BOOLVisx[n],visy[n];BOOLDasointx) {Visx[x] =true; for(inty =0; Y < NY; y++) {if(Visy[y])Continue; ll tmp = Lx[x] + ly[y]-g[x][y];if(TMP = =0) {Visy[y] =true;if(Linker[y] = =-1|| DFS (Linker[y])) {linker[y] = x;return true; } }Else if(Slack[y] > tmp) slack[y] = tmp; }return false;} ll KM () {memset(linker,-1,sizeof(linker));memset(Ly,0,sizeof(ly)); for(inti =0; i < nx;i++) {lx[i] =-inf; for(intj =0; J < ny;j++)if(G[i][j] > Lx[i]) lx[i] = G[i][j]; } for(intx =0; x < nx;x++) { for(inti =0; i < ny;i++) slack[i] = INF; while(true) {memset(VISX,false,sizeof(VISX));memset(Visy,false,sizeof(Visy));if(DFS (x)) Break; ll d = INF; for(inti =0; i < ny;i++)if(!visy[i] && d > slack[i]) d = slack[i]; for(inti =0; i < nx;i++)if(Visx[i]) lx[i]-= D; for(inti =0; i < ny;i++) {if(Visy[i]) ly[i] + = D;ElseSlack[i]-= D; }}} ll res =0; for(inti =0; i < ny;i++)if(Linker[i]! =-1) Res + = G[linker[i]][i];returnRes;}intimp[ the];intimb[ the];intMain () {intN,m; while(Cin>> n >> m) {if(n = =0&& m = =0) Break;memset(Imp,0,sizeof(imp));memset(IMB,0,sizeof(IMB));memset(g,0,sizeof(g)); NX = NY = max (n,m);intT,x,a,b;Cin>> T; while(t--) {Cin>> x; imp[x-1] =1; for(inti =0; I < NX; i++) {g[x-1][i] =-inf2;/ * cannot be set to INF because the set to INF is no point connected, but set to INF2 (less than INF) indicates that the edge can be connected, if you must connect, even if it is negative, there is no answer * /} }Cin>> T; while(t--) {Cin>> x; imb[x-1] =1; for(inti =0; I < NX; i++) {g[i][x-1] =-inf2; } } for(inti =0; I < n; i++) {Cin>> T; while(t--) {Cin>> a >> b; G[i][a-1] = b;if(Imp[i]) G[i][a-1] + = MOD;if(Imb[a-1]) G[i][a-1] + = MOD; }} ll ans = KM ();if(Ans <0)cout<<-1<< Endl;Else cout<< ans% MOD << Endl; }}/// 2 4 1 1 1 3 2 1 8 2 3 2 2 3 4 4 3 3 1 2 4 2 1 3 + 1 1 2 2 3
Solution Two: Maximum cost feasible flow in upper and lower bounds
Fake a start and end point, the capacity is 1, if there is a must do app or developer, this edge value is set to INF.
Here's the code:
Waiting to be mended
Regionals >> Asia-tehran >> 7530-cafebazaar Best Match "KM" "Maximum cost Flow"