明显一个裸的二分图的最小权匹配。
第一次是因为没注意两点之间有多条边,第二次用静态链表写错是在计算t的值的时候 与最大权匹配计算t的值一样了。。 忘记取反了
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 222
#define maxm 33333
struct node
{
int next, y, c;
}edge[maxm];
bool visx[maxn], visy[maxn];
int match[maxn], lx[maxn], ly[maxn], head[maxn];
int n, m, d;
void add(int x, int y, int w, int tot)
{
edge[tot].next= head[x];
edge[tot].y= y;
edge[tot].c= w;
head[x]= tot;
}
void init()
{
memset(match, -1, sizeof(match));
memset(head, -1, sizeof(head));
scanf("%d %d",&n,&m);
for(int i= 1; i<= m; i++)
{
int x, y, w;
scanf("%d %d %d",&x, &y, &w);
add(x, y, w, i);
}
for(int i= 1; i<= n; i++)
{
lx[i]= 11111;
ly[i]= 0;
for(int j= head[i]; j!= -1; j= edge[j].next)
lx[i]= min(lx[i], edge[j].c);
}
}
bool dfs(int u)
{
visx[u]= true;
for(int i= head[u]; i!= -1; i= edge[i].next)
if(!visy[ edge[i].y ])
{
int t= -(lx[u]+ ly[ edge[i].y ]- edge[i].c); //最小权匹配时这里取反
if(t== 0)
{
visy[ edge[i].y ]= 1;
if(match[ edge[i].y ]== -1 || dfs(match[ edge[i].y ]))
{
match[ edge[i].y ]= u;
return true;
}
}
else if(t> 0)
d= min(d, t);
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int ans= 0;
for(int i= 1; i<= n; i++)
{
memset(visx, false, sizeof(visx));
memset(visy, false, sizeof(visy));
d= 1<< 30;
while(!dfs(i))
{
for(int j= 1; j<= n; j++)
{
if(visx[j]) lx[j]+= d;
if(visy[j]) ly[j]-= d;
}
memset(visx, false, sizeof(visx));
memset(visy, false, sizeof(visy));
}
}
for(int i= 1; i<= n; i++)
ans+= lx[i]+ ly[i];
printf("%d\n",ans);
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 222
int map[maxn][maxn];
bool visx[maxn], visy[maxn];
int match[maxn], lx[maxn], ly[maxn];
int n, m, d;
void init()
{
memset(match, -1, sizeof(match));
scanf("%d %d",&n,&m);
for(int i= 1; i<= n; i++)
for(int j= 1; j<= n; j++)
map[i][j]= 11111;
for(int i= 1; i<= m; i++)
{
int x, y, w;
scanf("%d %d %d",&x, &y, &w);
map[x][y]= min(map[x][y], w);
}
for(int i= 1; i<= n; i++)
{
lx[i]= 11111;
ly[i]= 0;
for(int j= 1; j<= n; j++)
lx[i]= min(lx[i], map[i][j]);
}
}
bool dfs(int u)
{
visx[u]= 1;
for(int i= 1; i<= n; i++)
if(!visy[i] && map[u][i]!= 11111 && i!= u)
{
int t= -(lx[u]+ ly[i]- map[u][i]);
if(t== 0)
{
visy[i]= 1;
if(match[i]== -1 || dfs(match[i]))
{
match[i]= u;
return true;
}
}
else if(t> 0)
d= min(d, t);
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int ans= 0;
for(int i= 1; i<= n; i++)
{
memset(visx, false, sizeof(visx));
memset(visy, false, sizeof(visy));
d= 1<< 30;
while(!dfs(i))
{
for(int j= 1; j<= n; j++)
{
if(visx[j]) lx[j]+= d;
if(visy[j]) ly[j]-= d;
}
memset(visx, false, sizeof(visx));
memset(visy, false, sizeof(visy));
}
}
for(int i= 1; i<= n; i++)
ans+= lx[i]+ ly[i];
printf("%d\n",ans);
}
return 0;
}