题目大意:两台机器,分别有 (m) 个模式,初始时处于关机状态。有(k) 个任务,第 (i) 个任务可以在机器 (A) 上用 (a_i) 模式完成,也可以在机器 (B) 上用 (b_i) 模式完成。一台机器每更换一次模式需要关机一次。求完成所有任务所需的关机次数最小值。嘤语不好,轻喷
考虑网络流。可以由原点向机器 (A) 的 (n) 种模式连边,由机器 (B) 的 (m) 种模式向会点连边。对于每一个任务,由 (a_i) 向 (b_i) 连边。
跑一遍 (dinic) 即可
代码
#include<bits/stdc++.h>
namespace IO
{
using namespace std;
char buf[1<<22],Out[1<<22],*p1=buf,*p2=buf;
int p3=-1,f=0;
inline void file()
{
#ifdef NTFOrz
freopen("file.in","r",stdin);
#endif
}
inline char getchar()
{
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;
}
inline void flush(){fwrite(Out,1,p3+1,stdout),p3=-1;}
inline void check(){if (p3>(1<<21)) flush();}
inline void putchar(char a){Out[++p3]=a;check();}
inline void putline(string s)
{
int tmp=p3;
while (p3-tmp<s.size()) putchar(s[p3-tmp]);
putchar('
');
}
inline char gc()
{
char c=getchar();
while (!c||c=='
'||c==' ') c=getchar();
return c;
}
}
namespace my_std
{
using namespace std;
#define int long long
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#define getchar IO::getchar
#define putchar IO::putchar
#define Re register
#define rep(i,a,b) for (Re int i=(a);i<=(b);i++)
#define drep(i,a,b) for (Re int i=(a);i>=(b);i--)
#define repv(i,v) if (v.size()) rep(i,0,v.size()-1)
#define drepv(i,v) if (v.size()) drep(i,v.size()-1,0)
#define go(u) for (Re int i=head[(u)];i;i=e[i].nxt)
#define pf printf
#define writesp(x) write(x),putchar(' '),IO::check()
#define writeln(x) write(x),putchar('
'),IO::check()
#define mem(x,v) memset(x,v,sizeof(x))
#define pb push_back
#define NTF return
#define AKIOI 0
#define fir first
#define sec second
#define MP make_pair
#define all(x) x.begin(),x.end()
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef complex<double> Complex;
const int INF=0x7fffffff;
inline int read()
{
int sum=0,f=0;char c=getchar();
while (!isdigit(c)) f|=(c=='-'),c=getchar();
while (isdigit(c)) sum=(sum<<1)+(sum<<3)+(c^48),c=getchar();
return f?-sum:sum;
}
void write(int k)
{
if (k<0) putchar('-'),k=-k;
if (k>=10) write(k/10);
putchar(k%10+48);
}
#define templ template<typename T>
templ inline void chkmax(T &x,T y){if (x<y) x=y;}
templ inline void chkmin(T &x,T y){if (x>y) x=y;}
}
using namespace my_std;
const int N=510;
int n,m,k,cnt=1,dep[N<<1],head[N<<1],S,T;
struct edge
{
int to,nxt,flow;
}e[N*N];
inline void add(int u,int v,int flow){e[++cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt,e[cnt].flow=flow;}
inline void ins(int u,int v,int flow){add(u,v,flow),add(v,u,0);}
inline bool bfs()
{
static queue<int>q;
mem(dep,0),dep[S]=1,q.push(S);
while (!q.empty())
{
int u=q.front();
go(u)
{
int v=e[i].to;
if (e[i].flow&&!dep[v])
{
dep[v]=dep[u]+1;
q.push(v);
}
}
q.pop();
}
return dep[T];
}
int dfs(int u,int in)
{
if (u==T) return in;
int out=0;
go(u)
{
int v=e[i].to;
if (e[i].flow&&dep[v]==dep[u]+1)
{
int res=dfs(v,min(in,e[i].flow));
in-=res,out+=res,e[i].flow-=res,e[i^1].flow+=res;
}
}
if (out==0) dep[u]=0;
return out;
}
inline int dinic(){int ans=0;while (bfs()) ans+=dfs(S,INF);return ans;}
inline void clear(){cnt=1,mem(head,0);}
inline void solve()
{
m=read(),k=read();
S=0,T=n+m+1;
rep(i,1,n) ins(S,i,1);
rep(i,1,m) ins(i+n,T,1);
rep(i,1,k)
{
int TAT=read(),u=read(),v=read()+n;
if (u*v==0) continue;
ins(u,v,INF);
}
writeln(dinic());
clear();
}
signed main()
{
IO::file();
n=read();
while (n) solve(),n=read();
IO::flush();
return 0;
}