Global round 6 D、E

D

题意:

很简单,一张图,债务关系,请缩小关系,使得关系越简单越好,具体体现为,边权总和最小。

题解

每个人只关心借了多少钱和借出去多少。
我们把所有人借了的钱分别从借出去的人里面分配,一个一个分。
即可。

#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define sf(x) scanf("%d",&x)
using namespace std;
 
typedef long long ll;
const int maxn = 200050;
 
int n,m;
ll sum[maxn];
queue<pair<ll,int> >P,Q;
vector<pair<ll,int> >G[maxn];
 
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v;ll d;
        scanf("%d%d%lld",&u,&v,&d);
        sum[u]-=d;
        sum[v]+=d;
    }
    for(int i=1;i<=n;i++){
        if(sum[i]==0)continue;
        if(sum[i]<0)P.push(make_pair(-sum[i],i));
        else Q.push(make_pair(sum[i],i));
    }
    m=0;
    while(!P.empty()){
        ll val=P.front().first;
        int u=P.front().second;
        P.pop();
        //cout<<u<<":"<<val<<endl;
        while(!Q.empty()){
            int v=Q.front().second;
            ll have=Q.front().first;
            //cout<<v<<" "<<have<<endl;
            if(have<val){
                G[u].push_back(make_pair(have,v));
                val-=have;
                Q.pop();
                m++;
            }
            else{
                Q.front().first-=val;
                G[u].push_back(make_pair(val,v));
                m++;
                if(Q.front().first==0)Q.pop();//cout<<Q.front().second<<endl;
                break;
            }
        }
    }
    cout<<m<<endl;
    for(int i=1;i<=n;i++){
        for(int j=0;j<G[i].size();j++){
            cout<<i<<" "<<G[i][j].second<<" "<<G[i][j].first<<endl;
        }
    }
}

E

题意:

需要 n n 个物品,每个物品需要 a [ i ] a[i] 个,有成就可以获得,一旦达到某个物品的多少个就可以送一种物品的一个。
这个成就所需数量 > 0 & & < a [ i ] >0\&\&<a[i]

题解:

根据条件,也就是我们在到达所需的过程中一定会完成成就,也就是说,每个成就都会被利用到。[官网证明没看懂,以后再来看]
统计即可,记住成就不会存在相同条件,相同条件会覆盖。
答案是 m a x ( a [ i ] c [ i ] , 0 ) \sum max(a[i]-c[i],0) , c [ i ] c[i] 指的有多少个成就会送一个免费 i i

#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define sf(x) scanf("%d",&x)
using namespace std;
 
typedef long long ll;
const int maxn = 200050;
 
map<pair<int,int>,int>mp;
map<int,int>Mp;
int a[maxn];
 
int main(){
    int n;cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    ll s=0;
    for(int i=1;i<=n;i++)s+=a[i];
    int m;cin>>m;
    ll h=0;
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        int id=mp[make_pair(x,y)];
        if(id){
            Mp[id]--;
            if(Mp[id]<a[id])h--;
            mp[make_pair(x,y)]=z;
            Mp[z]++;
            if(Mp[z]<=a[z])h++;
        }
        else{
            mp[make_pair(x,y)]=z;
            Mp[z]++;
            if(Mp[z]<=a[z])h++;
        }
        cout<<s-h<<endl;
    }
}
发布了203 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/mxYlulu/article/details/104029269
今日推荐