# Top Trading Cycle (最適循環交易法) ## Definition **Top trading cycle (TTC)** is an algorithm for trading indivisible items without using money * 在**不使用金錢**交易 * 每人只有**一個物品**可以交易 ## How does it work ? & Example **The algorithm works as follows :** * 詢問每個人想交換的**志願序** * 不須列出志願序**低於**自身的 ( i.e. 維持現狀比交易好 ) 進而列出表格 : | Agent | A | B | C | D | E | F | G | | ---------- | --- | --- | --- | --- | --- | --- | --- | | 1st choice | E | C | D | A | D | G | A | | 2nd choice | F | D | E | B | E | A | G | | 3rd choice | G | E | B | C | | B | | | 4th choice | A | F | G | D | | C | | | 5th choice | | G | A | | | D | | | 6th choice | | A | C | | | E | | | 7th choice | | | | | | F | | * 畫出每個人**指向自己最高志願序**的箭頭 * 觀察是否可以**形成一個環** * 若可以形成**環** , ==將環去除== i.e. 形成環的人交易 (==自身可以形成一環==) * 繼續上述的步驟 **In this example :** 在第一志願序中 : A ⇒ E , D ⇒ A , E ⇒ D ( 形成一個環 ! ) * 將他們都標記 (其他人無法再跟他們交易) 接下來的志願序中 : ( 對於每個人最好的志願序中 ) B ⇒ C , C ⇒ B , F ⇒ G , G ⇒ G (B,C形成一環) (G自環) (F維持原樣) **result :** | Agent | A | B | C | D | E | F | G | | ---------- | --- | --- | --- | --- | --- | --- | --- | | 1st choice | E | C | | A | D | | | | 2nd choice | | | | | | | G | | 3rd choice | | | B | | | | | | 4th choice | | | | | | | | | 5th choice | | | | | | | | | 6th choice | | | | | | | | | 7th choice | | | | | | F | | ## Turn TTC to code [Run my code online](https://repl.it/@jason810496/TopTradingCycle#main.cpp) ```c #include<bits/stdc++.h> using namespace std; int n,cycle_cnt=0,cnt=0; vector<bool> visited_list; vector<vector<int> > graph; void trans(string temp,int i){ stringstream ss; int num; ss.str(temp); while(ss>>num){ num--; graph[i].push_back(num); } } void input(){ string temp; cout<<"Top Trading Cycle Algorithm\n"; cout<<"There are N items in this case\n"; cout<<"Input N : ",cin>>n,cout<<'\n'; graph.resize(n),visited_list.resize(n); cout<<"For each case :\ninput your item's number which you want to exchange"; cout<<"form Top\"(most preferred) to low , until your item\n"; cout<<"(including your item i.e. exchanged situation is worst than original situation)\n"; cout<<"Eg : case 1: 3 4 2 5 1\n"; cout<<" input data in form of :\nnum_i num_j num_k ... ( with space between each number)\n\n"; getline(cin,temp); for(int i=0;i<n;i++){ cout<<"For case "<<i+1<<" , input your sequences :\n"; getline(cin,temp); trans(temp,i); } cout<<'\n'; } void DFS_cycle(int cur,set<int> s,vector<int> cycle_list){ if(s.find(cur)!=s.end()){ cycle_cnt++; int ele_cnt=0; bool index=false; for(auto &i:cycle_list){ if(i==cur){ cout<<"cycle "<<cycle_cnt<<" :\n"; index=true; } if(index){ cout<<i+1<<' '; cnt++; ele_cnt++; visited_list[i]=1; } } if(ele_cnt==1){ cout<<" (original situation is better)"; } cout<<'\n'; return; } s.insert(cur); cycle_list.push_back(cur); for(auto i:graph[cur]){ if(!visited_list[i]){ DFS_cycle(i,s,cycle_list); break; } } } void check(){ cycle_cnt=0; cnt=0; while(cnt<n){ for(int i=0;i<n;i++){ if(visited_list[i]) continue; for(auto &j:graph[i]){ if(!visited_list[j]){ set<int> s; vector<int> cycle_list; s.insert(i),cycle_list.push_back(i); DFS_cycle(j,s,cycle_list); break; } } } } } int main(){ input(); check(); return 0; } ```