题目链接:https://vjudge.net/problem/UVA-814
题目翻译摘自《算法禁赛入门经典》
题目大意
本题的任务为模拟发送邮件时 MTA(邮件传输代理)之间的交互。所谓 MTA,就是 email地址格式 user@mtaname 的“后面部分”。当某人从 user1@mta1 发送给另一个人 user2@mta2 时,这两个 MTA 将会通信。如果两个收件人属于同一个 MTA,发送者的 MTA 只需与这个 MTA 通信一次就可以把邮件发送给这两个人。
输入每个 MTA 里的用户列表,对于每个发送请求(输入发送者和接收者列表),按顺序输出所有 MTA 之间的 SMTP(简单邮件协议)交互。协议细节参见原题。
发送人 MTA 连接收件人 MTA 的顺序应该与在输入中第一次出现的顺序一致。
如果连接某个 MTA 之后发现所有收件人都不存在,则不应该发送DATA。所有用户名均 由不超过15个字母和数字组成。
发信人一定存在。
分析
略。
代码如下
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 5 #define Rep(i,n) for (int i = 0; i < (n); ++i) 6 #define For(i,s,t) for (int i = (s); i <= (t); ++i) 7 #define rFor(i,t,s) for (int i = (t); i >= (s); --i) 8 #define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i) 9 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i) 10 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i) 11 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) 12 13 #define pr(x) cout << #x << " = " << x << " " 14 #define prln(x) cout << #x << " = " << x << endl 15 16 #define LOWBIT(x) ((x)&(-x)) 17 18 #define ALL(x) x.begin(),x.end() 19 #define INS(x) inserter(x,x.begin()) 20 21 #define ms0(a) memset(a,0,sizeof(a)) 22 #define msI(a) memset(a,inf,sizeof(a)) 23 #define msM(a) memset(a,-1,sizeof(a)) 24 25 #define MP make_pair 26 #define PB push_back 27 #define ft first 28 #define sd second 29 30 template<typename T1, typename T2> 31 istream &operator>>(istream &in, pair<T1, T2> &p) { 32 in >> p.first >> p.second; 33 return in; 34 } 35 36 template<typename T> 37 istream &operator>>(istream &in, vector<T> &v) { 38 for (auto &x: v) 39 in >> x; 40 return in; 41 } 42 43 template<typename T1, typename T2> 44 ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) { 45 out << "[" << p.first << ", " << p.second << "]" << " "; 46 return out; 47 } 48 49 inline int gc(){ 50 static const int BUF = 1e7; 51 static char buf[BUF], *bg = buf + BUF, *ed = bg; 52 53 if(bg == ed) fread(bg = buf, 1, BUF, stdin); 54 return *bg++; 55 } 56 57 inline int ri(){ 58 int x = 0, f = 1, c = gc(); 59 for(; c<48||c>57; f = c=='-'?-1:f, c=gc()); 60 for(; c>47&&c<58; x = x*10 + c - 48, c=gc()); 61 return x*f; 62 } 63 64 template<class T> 65 inline string toString(T x) { 66 ostringstream sout; 67 sout << x; 68 return sout.str(); 69 } 70 71 inline int toInt(string s) { 72 int v; 73 istringstream sin(s); 74 sin >> v; 75 return v; 76 } 77 78 typedef long long LL; 79 typedef unsigned long long uLL; 80 typedef pair< double, double > PDD; 81 typedef pair< int, int > PII; 82 typedef pair< int, PII > PIPII; 83 typedef pair< string, int > PSI; 84 typedef pair< int, PSI > PIPSI; 85 typedef set< int > SI; 86 typedef set< PII > SPII; 87 typedef vector< int > VI; 88 typedef vector< VI > VVI; 89 typedef vector< SI > VSI; 90 typedef vector< PII > VPII; 91 typedef map< int, int > MII; 92 typedef map< int, string > MIS; 93 typedef map< int, PII > MIPII; 94 typedef map< PII, int > MPIII; 95 typedef map< string, int > MSI; 96 typedef map< string, string > MSS; 97 typedef map< PII, string > MPIIS; 98 typedef map< PII, PII > MPIIPII; 99 typedef multimap< int, int > MMII; 100 typedef multimap< string, int > MMSI; 101 //typedef unordered_map< int, int > uMII; 102 typedef pair< LL, LL > PLL; 103 typedef vector< LL > VL; 104 typedef vector< VL > VVL; 105 typedef priority_queue< int > PQIMax; 106 typedef priority_queue< int, VI, greater< int > > PQIMin; 107 const double EPS = 1e-8; 108 const LL inf = 0x7fffffff; 109 const LL infLL = 0x7fffffffffffffffLL; 110 const LL mod = 1e9 + 7; 111 const int maxN = 1e4 + 7; 112 const LL ONE = 1; 113 const LL evenBits = 0xaaaaaaaaaaaaaaaa; 114 const LL oddBits = 0x5555555555555555; 115 116 struct User{ 117 string mail, name, addr; 118 119 User() {} 120 User(string s) { 121 mail = s; 122 name = s.substr(0, s.find('@')); 123 addr = s.substr(s.find('@') + 1); 124 } 125 }; 126 127 MSS mta; // name->address 128 129 int main(){ 130 //freopen("MyOutput.txt","w",stdout); 131 //freopen("input.txt","r",stdin); 132 //INIT(); 133 string tmp, msg; 134 while(cin >> tmp) { 135 if(tmp == "*") break; 136 string loc; 137 int n; 138 139 cin >> loc >> n; 140 Rep(i, n) { 141 cin >> tmp; 142 mta[tmp] = loc; 143 } 144 } 145 146 while(cin >> tmp) { 147 if(tmp == "*") break; 148 User from(tmp); 149 vector< User > to; 150 map< string, VI > msv; // 顺序存相同地址的人 151 set< string > names; // 判重用 152 153 while(cin >> tmp) { 154 if(tmp == "*") break; 155 User t(tmp); 156 157 if(names.find(t.name) != names.end()) continue; 158 else names.insert(t.name); 159 to.PB(t); 160 msv[t.addr].PB(to.size() - 1); 161 } 162 163 getline(cin, msg); // ' ' 164 while(getline(cin, tmp)) { 165 if(tmp == "*") break; 166 msg += " " + tmp + " "; 167 } 168 169 foreach(i, to) { 170 if(msv.find(i->addr) != msv.end()) { 171 printf("Connection between %s and %s ", from.addr.c_str(), i->addr.c_str()); 172 printf(" HELO %s ", from.addr.c_str()); 173 printf(" 250 "); 174 printf(" MAIL FROM:<%s> ", from.mail.c_str()); 175 printf(" 250 "); 176 177 int cnt = 0; 178 foreach(j, msv[i->addr]) { 179 printf(" RCPT TO:<%s> ", to[*j].mail.c_str()); 180 if(mta.find(to[*j].name) != mta.end()) printf(" 250 "), ++cnt; 181 else printf(" 550 "); 182 } 183 msv.erase(i->addr); 184 185 if(cnt) { 186 printf(" DATA "); 187 printf(" 354 "); 188 printf("%s", msg.c_str()); 189 printf(" . "); 190 printf(" 250 "); 191 } 192 193 printf(" QUIT "); 194 printf(" 221 "); 195 } 196 } 197 } 198 return 0; 199 }