1. 程式人生 > >EZOI2018屆出題組 第一場比賽:無人AK 題解

EZOI2018屆出題組 第一場比賽:無人AK 題解

這是這場比賽的題解,雖然題不難,但是資料還是非常坑的。 T1: 題面非常簡單,意思就是輸入a,b,輸出a * b.但是題目有坑,intger是在pascal中的short,故所有變數都應是short型別的。

#include <bits/stdc++.h>
using namespace std;
int a ,b;
int main()
{
	cin>>a>>b;
cout<<short(a*b);
return 0;
}

T2: 看起來也非常簡單,就是一個非常裸的模擬。但是資料非常大,全部讀完基本就爆了。讀一讀題,易知是先輸入1,後輸入2,故可以讀完1的即可,因為可以用1的個數求出2的個數。

#include <bits/stdc++.h>
using namespace std;
int n,m;
int pd = 0;
int ans; 
int main()
{
	scanf("%d%d",&n,&m);
	int x;
	int np = m;
	register int tp = 0;
	while(m--)
	{
       scanf("%d",&x);
       if(x == 1)
       tp++;
	   if(x == 2)
	   {
	   	 break;
		}	
	}
	ans += tp;
	ans += min(n + tp,np - tp);
	printf("%d",ans);
	return 0;
}

T3: 比較裸,最大費用最大流,超源連人,人連物,物連超源,邊權自然是魅力值。

#include<bits/stdc++.h>
using namespace std;
struct qwq{
    int v;
    int cap;
    int cost;
    int nxt;
}edge[300001];
int cnt=-1;
int head[300001];
void add(int u,int v,int cap,int cost){
    edge[++cnt].nxt=head[u];
    edge[cnt].v=v;
    edge[cnt].cap=cap;
    edge[cnt].cost=cost;
    head[u]=cnt;
}
void addedge(int u,int v,int cap,int cost){
    add(u,v,cap,cost);
    add(v,u,0,-cost);
}
int incf[300001];
int pre[300001];
int dis[300001];
bool vis[300001];
int n,m;
bool spfa(int s,int t){
    for(int i=0;i<=n+m+1;++i){
    	dis[i]=INT_MAX;
    	vis[i]=0;
    }
    queue<int> q;
    q.push(s);
    dis[s]=0;
    vis[s]=true;
    incf[s]=INT_MAX;
    while(!q.empty()){
        int u=q.front();
        vis[u]=false;
        q.pop();
        for(int i=head[u];~i;i=edge[i].nxt){
            int v=edge[i].v;
            int cap=edge[i].cap;
            int cost=edge[i].cost;
            if(cap>0&&dis[v]>dis[u]+cost){
                dis[v]=dis[u]+cost;
                incf[v]=min(incf[u],cap);
                pre[v]=i;
                if(!vis[v]){
                    q.push(v);
                    vis[v]=true;
                }
            }
        }
    }
    return dis[t]!=INT_MAX;
}
int ans,maxflow;
void mcmf(int s,int t){
    while(spfa(s,t)){
        int x=t;
        while(x!=s){
            int i=pre[x];
            edge[i].cap-=incf[t];
            edge[i^1].cap+=incf[t];
            x=edge[i^1].v;
        }
        ans+=incf[t]*dis[t];
        maxflow+=incf[t];
    }
}
int main(){
    memset(head,-1,sizeof(head));
    int s,t;
    scanf("%d%d",&n,&m);
    s=0;
    t=n+m+1;
    for(int i=1;i<=n;++i){
    	addedge(s,i,1,0);
    }
    for(int i=1;i<=m;++i){
        addedge(i+n,t,1,0);
    }
    for(int i=1;i<=n;++i){
        int tmp;
        scanf("%d",&tmp);
        while(tmp--){
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            addedge(i,t1+n,1,-t2);
        } 
    }
    mcmf(s,t);
    printf("%d",-ans);
} 

這份題解就寫到這裡了,希望在我們打比賽的時候haiq01別來。。。。