uva 538(简单图论 入度出度)
题意:这道题以前在cf上碰见过类似的,虽然比较简单但还是卡了半天,主要是因为题目没读清楚。题意是有n个人<20他们之间有一些欠钱关系。然后让你设计最多n-1个操作来吧他们之间的钱还清。
思路:统计入度出度,然后我们每次把出度最大的和入度最大的两个人挑出来然后把它们的钱平分一下。直到所有人的读书都为0。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <cstring> 6 #include <algorithm> 7 #include <queue> 8 #include <stack> 9 #include <vector> 10 #include <set> 11 #include <map> 12 #define MP(a, b) make_pair(a, b) 13 #define PB(a) push_back(a) 14 15 using namespace std; 16 17 typedef long long ll; 18 typedef pair<int ,int> pii; 19 typedef pair<unsigned int, unsigned int> puu; 20 typedef pair<int ,double> pid; 21 typedef pair<ll, int> pli; 22 23 const int INF = 0x3f3f3f3f; 24 const double eps = 1e-6; 25 const int LEN = 101; 26 map<string, int> mp; 27 map<int, string> rmp; 28 int ind[LEN], kase = 1; 29 30 int main() 31 { 32 // freopen("in.txt", "r", stdin); 33 34 int n, m, val, tag; 35 char s1[101], s2[101]; 36 while(scanf("%d%d", &n, &m)!=EOF){ 37 if(!n && !m) break; 38 memset(ind, 0, sizeof ind); 39 mp.clear(); rmp.clear(); 40 for(int i=0; i<n; i++){ 41 scanf("%s", s1); 42 mp[s1] = i;rmp[i] = s1; 43 } 44 for(int i=0; i<m; i++){ 45 scanf("%s%s%d", s1, s2, &val); 46 ind[mp[s1]]-=val;ind[mp[s2]]+=val; 47 } 48 priority_queue<pii> qa, qb; 49 while(!qa.empty())qa.pop(); 50 while(!qb.empty())qb.pop(); 51 for(int i=0; i<n; i++){ 52 if(ind[i]>0) qa.push(MP(ind[i], i)); 53 if(ind[i]<0) qb.push(MP(-ind[i], i)); 54 } 55 printf("Case #%d\n", kase++); 56 while(!qa.empty() || !qb.empty()){ 57 pii a = qa.top();qa.pop(); 58 pii b = qb.top();qb.pop(); 59 val = min(a.first, b.first); 60 a.first-= val; 61 b.first-= val; 62 if(a.first!=0){qa.push(a);} 63 if(b.first!=0){qb.push(b);} 64 cout << rmp[a.second] << ' ' << rmp[b.second] << ' ' << val << endl; 65 } 66 printf("\n"); 67 } 68 return 0; 69 }
奔跑吧!少年!趁着你还年轻