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
题意:
需要
个物品,每个物品需要
个,有成就可以获得,一旦达到某个物品的多少个就可以送一种物品的一个。
这个成就所需数量
题解:
根据条件,也就是我们在到达所需的过程中一定会完成成就,也就是说,每个成就都会被利用到。[官网证明没看懂,以后再来看]
统计即可,记住成就不会存在相同条件,相同条件会覆盖。
答案是
,
指的有多少个成就会送一个免费
#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;
}
}