Cyclic Tour
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)
Total Submission(s): 1269 Accepted Submission(s): 659
Problem Description There are N cities in our country, and M one-way roads connecting them. Now Little Tom wants to make several cyclic tours, which satisfy that, each cycle contain at least two cities, and each city belongs to one cycle exactly. Tom wants the total length of all the tours minimum, but he is too lazy to calculate. Can you help him?
Input There are several test cases in the input. You should process to the end of file (EOF).
The first line of each test case contains two integers N (N ≤ 100) and M, indicating the number of cities and the number of roads. The M lines followed, each of them contains three numbers A, B, and C, indicating that there is a road from city A to city B, whose length is C. (1 ≤ A,B ≤ N, A ≠ B, 1 ≤ C ≤ 1000).
Output Output one number for each test case, indicating the minimum length of all the tours. If there are no such tours, output -1.
Sample Input
6 9
1 2 5
2 3 5
3 1 10
3 4 12
4 1 8
4 6 11
5 4 7
5 6 9
6 5 4
6 5
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1
Sample Output
42
-1
Hint
In the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42.
Author [email protected]
Source HDU 2007 Programming Contest - Final
Recommend lcy
這個題目應該講其實是很不錯的,但是我現在覺得建圖真是一個大問題,因為實在想不到為什麼這樣建圖,這樣很是無奈的,唉,還是 做題目太少了
這就是建圖的結果,然後我們用最大流和N比較,因為每個流之間都是1,是以如果是n,則證明是可以的,否則就不可以
#include <iostream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <queue>
using namespace std;
int sumFlow;
#define MAXN 505
#define MAXM 10005
#define INF 1000000000
struct Edge
{
int u, v, cap, cost;
int next;
}edge[MAXM<<2];
int NE;
int head[MAXN], dist[MAXN], pp[MAXN];
bool vis[MAXN];
char map[MAXN][MAXN];
void init()
{
NE = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int cap, int cost)
{
edge[NE].u = u; edge[NE].v = v; edge[NE].cap = cap; edge[NE].cost = cost;
edge[NE].next = head[u]; head[u] = NE++;
edge[NE].u = v; edge[NE].v = u; edge[NE].cap = 0; edge[NE].cost = -cost;
edge[NE].next = head[v]; head[v] = NE++;
}
bool SPFA(int s, int t, int n)
{
int i, u, v;
queue <int> qu;
memset(vis,false,sizeof(vis));
memset(pp,-1,sizeof(pp));
for(i = 0; i <= n; i++) dist[i] = INF;
vis[s] = true; dist[s] = 0;
qu.push(s);
while(!qu.empty())
{
u = qu.front(); qu.pop(); vis[u] = false;
for(i = head[u]; i != -1; i = edge[i].next)
{
v = edge[i].v;
if(edge[i].cap && dist[v] > dist[u] + edge[i].cost)
{
dist[v] = dist[u] + edge[i].cost;
pp[v] = i;
if(!vis[v])
{
qu.push(v);
vis[v] = true;
}
}
}
}
if(dist[t] == INF) return false;
return true;
}
int MCMF(int s, int t, int n) // minCostMaxFlow
{
int flow = 0; // 總流量
int i, minflow, mincost;
mincost = 0;
while(SPFA(s, t, n))
{
minflow = INF + 1;
for(i = pp[t]; i != -1; i = pp[edge[i].u])
if(edge[i].cap < minflow)
minflow = edge[i].cap;
flow += minflow;
for(i = pp[t]; i != -1; i = pp[edge[i].u])
{
edge[i].cap -= minflow;
edge[i^1].cap += minflow;
}
mincost += dist[t] * minflow;
}
sumFlow = flow; // 最大流
return mincost;
}
int main()
{
int n, m;
int u, v, c;
int i,j;
while (scanf("%d%d", &n, &m)!=EOF)
{
init();
int S = 0;
int T = 2*n+1;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&c);
addedge(u,v+n,1,c);
}
for(i=1;i<=n;i++)
{
addedge(0,i,1,0);
addedge(n+i,T,1,0);
}
int ans = MCMF(S, T, T+1);
if(sumFlow!=n)
printf("-1\n");
else
printf("%d\n", ans);
}
return 0;
}