Pagini recente » Cod sursa (job #2349148) | Cod sursa (job #2270010) | Cod sursa (job #1251188) | Cod sursa (job #2903639) | Cod sursa (job #902218)
Cod sursa(job #902218)
#include<fstream>
#define nmax 604
#define inf 1<<30
using namespace std;
struct nod_lista{
int val;
nod_lista *link;
};
nod_lista *G[nmax],*Last[nmax];
int cap[nmax][nmax],flux[nmax][nmax],Q[4*nmax],T[nmax],dist[nmax],cost[nmax][nmax],
ed[nmax][nmax],LEFT[nmax],RIGHT[nmax],bL[nmax],bR[nmax],viz[nmax];
int L,R,E,S,D,NR,K,nr,KL,KR,N,FLUX;
void adauga(int unde,int ce)
{
nod_lista *q=new nod_lista;
q->link=NULL;
q->val=ce;
if(!G[unde])
G[unde]=Last[unde]=q;
else
{
Last[unde]->link=q;
Last[unde]=q;
}
}
void citeste()
{
ifstream f("cmcm.in");
int i,x,y,c;
f>>L>>R>>E;
S=L+R+1;
D=L+R+2;
N=D;
for(i=1;i<=E;i++)
{
f>>x>>y>>c;
adauga(x,y+L);
adauga(y+L,x);
cap[x][y+L]=1;
cost[x][y+L]=c;
cost[y+L][x]=-c;
ed[x][y+L]=i;
if(!bL[x])
{
LEFT[++KL]=x;
bL[x]=1;
}
if(!bR[y])
{
RIGHT[++KR]=y;
bR[y]=1;
}
}
}
void construieste_graf()
{
int i;
for(i=1;i<=L;i++)
{
adauga(S,LEFT[i]);
adauga(LEFT[i],S);
cap[S][LEFT[i]]=1;
}
for(i=1;i<=R;i++)
{
adauga(RIGHT[i]+L,D);
adauga(D,RIGHT[i]+L);
cap[RIGHT[i]+L][D]=1;
}
}
//graful e gata
int BellmanFord(int S,int D)
{
int p,q,nod,vecin;
nod_lista *it;
for(int i=1;i<=N;i++)
dist[i]=inf;
dist[S]=0;
p=q=0;
Q[++q]=S;
viz[S]=1;
while(p<q)
{
nod=Q[++p];
viz[nod]=0;
it=G[nod];
while(it)
{
vecin=it->val;
if(cap[nod][vecin]-flux[nod][vecin]>0 &&
dist[vecin]>dist[nod]+cost[nod][vecin])
{
dist[vecin]=dist[nod]+cost[nod][vecin];
T[vecin]=nod;
if(!viz[vecin])
Q[++q]=vecin,viz[vecin]=1;
}
it=it->link;
}
}
if(dist[D]!=inf)
return 1;
return 0;
}
void saturare()
{
int nod,cmin;
cmin=inf;
nod=D;
while(nod!=S)
{
if(cap[T[nod]][nod]-flux[T[nod]][nod]<cmin)
cmin=cap[T[nod]][nod]-flux[T[nod]][nod];
nod=T[nod];
}
nod=D;
while(nod!=S)
{
flux[T[nod]][nod]+=cmin;
flux[nod][T[nod]]-=cmin;
nod=T[nod];
}
FLUX+=cmin;
K+=cmin*dist[D];
}
void rezolva()
{
construieste_graf();
while(BellmanFord(S,D))
saturare();
}
void scrie()
{
int stop;
ofstream g("cmcm.out");
g<<FLUX<<' '<<K<<'\n';
for(int i=1;i<=L;i++)
{
stop=0;
for(int j=1;j<=R && !stop;j++)
if(flux[LEFT[i]][RIGHT[j]+L]>0)
{
g<<ed[LEFT[i]][RIGHT[j]+L]<<' ';
stop=1;
}
}
g.close();
}
int main()
{
citeste();
rezolva();
scrie();
return 0;
}