#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; const char infile[] = "cmcm.in"; const char outfile[] = "cmcm.out"; ifstream fin(infile); ofstream fout(outfile); const int MAXN = 305; const int oo = 0x3f3f3f3f; typedef vector Graph[2*MAXN]; typedef vector :: iterator It; const inline int min(const int &a, const int &b) { if( a > b ) return b; return a; } const inline int max(const int &a, const int &b) { if( a < b ) return b; return a; } const inline void Get_min(int &a, const int b) { if( a > b ) a = b; } const inline void Get_max(int &a, const int b) { if( a < b ) a = b; } int Capacity[2*MAXN][2*MAXN], Flow[2*MAXN][2*MAXN]; int Cost[2*MAXN][2*MAXN], Father[2*MAXN]; int dp[2*MAXN], Edge[MAXN][2*MAXN]; Graph G; int Source, Sink, _match, _minCostFlow, N, M, E; bitset <2*MAXN> inQ; queue Q; inline bool BellmanFord() { memset(dp, oo, sizeof(dp)); dp[Source] = 0; Q.push(Source); inQ[Source] = true; while(!Q.empty()) { int Node = Q.front(); Q.pop(); inQ[Node] = false; //if(Node == Sink) // continue; for(It it = G[Node].begin(), fin = G[Node].end(); it != fin ; ++ it) if(Capacity[Node][*it] - Flow[Node][*it] > 0 && dp[*it] > dp[Node] + Cost[Node][*it]) { dp[*it] = dp[Node] + Cost[Node][*it]; Father[*it] = Node; if(!inQ[*it]) { Q.push(*it); inQ[*it] = true; } } } return dp[Sink] != oo; } int main() { fin >> N >> M >> E; for(int i = 1 ; i <= E ; ++ i) { int x, y, z; fin >> x >> y >> z; y += N; Edge[x][y] = i; G[x].push_back(y); G[y].push_back(x); Capacity[x][y] = 1; Capacity[y][x] = 0; Cost[x][y] = z; Cost[y][x] = -z; } Source = 0; Sink = N + M + 1; for(int i = 1 ; i <= N ; ++ i) { G[Source].push_back(i); G[i].push_back(Source); Capacity[Source][i] = 1; Capacity[i][Source] = 0; Cost[Source][i] = 0; } for(int i = 1 + N ; i <= N + M ; ++ i) { G[i].push_back(Sink); G[Sink].push_back(i); Capacity[i][Sink] = 1; Capacity[Sink][i]= 0; Cost[i][Sink] = 0; Cost[Sink][i] = 0; } while(BellmanFord()) { int bottleNeck = oo; for(int i = Sink ; i != Source ; i = Father[i]) bottleNeck = min(bottleNeck, Capacity[Father[i]][i] - Flow[Father[i]][i]); for(int i = Sink ; i != Source ; i = Father[i]) { Flow[Father[i]][i] += bottleNeck;; Flow[i][Father[i]] -= bottleNeck; } _match += bottleNeck; _minCostFlow += dp[Sink]; } fout << _match << ' ' << _minCostFlow << '\n'; for(int i = 1 ; i <= N ; ++ i) for(int j = 1 + N ; j <= N + M ; ++ j) if(Flow[i][j]) fout << Edge[i][j] << ' '; fin.close(); fout.close(); return 0; }