zoukankan      html  css  js  c++  java
  • [题解]UVA1194 Machine Schedule

    传送门

    题目大意:两台机器,分别有 (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;
    }
    
    
  • 相关阅读:
    公输盘
    电脑机器刷BIOS
    八皇后问题的实现
    安装msdn出现的问题及解决
    加密推荐书籍
    C++待解
    atan()与atan2()
    Win32/MFC/COM学习推荐书籍
    C++问题
    windows2000 sp4下载
  • 原文地址:https://www.cnblogs.com/ZHANG-SHENG-HAO/p/13362619.html
Copyright © 2011-2022 走看看