Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 13464 | Accepted: 5101 |
Description
Input
Output
Sample Input
4 5 1 2 1 2 3 1 3 4 1 1 3 2 2 4 2
Sample Output
6
题意:给你N个农田、M条无向边以及每条边的长度。现在让你从1走到N再从N走回1,要求不能走重复的边。问你所走的路径总长的最小值。题目保证1到N至少会存在两条边不重复的路径。
很简单的题目,就不多说了。
建图:超级源点source,超级汇点sink
1,source连点1,容量为2,费用为0;
2,对题目给出的无向边建双向边,容量为1(意味着该边只能走一次),费用为边的长度;
3,N到sink建边,容量为2,费用为0。
最后跑一次最小费用最大流就可以了。
AC代码:数据不会超int
#include
#include
#include
#include
#include
#include
#define MAXN 1010
#define MAXM 50000+10
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
struct Edge
{
int from, to, cap, flow, cost, next;
};
Edge edge[MAXM];
int head[MAXN], edgenum;
int dist[MAXN];
int pre[MAXN];
bool vis[MAXN];
int N, M;
int source, sink;
void init()
{
edgenum = 0;
memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int w, int c)
{
Edge E1 = {u, v, w, 0, c, head[u]};
edge[edgenum] = E1;
head[u] = edgenum++;
Edge E2 = {v, u, 0, 0, -c, head[v]};
edge[edgenum] = E2;
head[v] = edgenum++;
}
void getMap()
{
int a, b, c;
source = 0, sink = N+1;
while(M--)
{
scanf("%d%d%d", &a, &b, &c);
addEdge(a, b, 1, c);//建双向边
addEdge(b, a, 1, c);
}
addEdge(source, 1, 2, 0);//超级源点连起点
addEdge(N, sink, 2, 0);//终点连超级汇点
}
bool SPFA(int s, int t)
{
queue Q;
memset(dist, INF, sizeof(dist));
memset(vis, false, sizeof(vis));
memset(pre, -1, sizeof(pre));
dist[s] = 0;
vis[s] = true;
Q.push(s);
while(!Q.empty())
{
int u = Q.front();
Q.pop();
vis[u] = false;
for(int i = head[u]; i != -1; i = edge[i].next)
{
Edge E = edge[i];
if(dist[E.to] > dist[u] + E.cost && E.cap > E.flow)
{
dist[E.to] = dist[u] + E.cost;
pre[E.to] = i;
if(!vis[E.to])
{
vis[E.to] = true;
Q.push(E.to);
}
}
}
}
return pre[t] != -1;
}
void MCMF(int s, int t, int &cost)
{
cost = 0;
while(SPFA(s, t))
{
int Min = INF;
for(int i = pre[t]; i != -1; i = pre[edge[i^1].to])
{
Edge E = edge[i];
Min = min(Min, E.cap - E.flow);
}
for(int i = pre[t]; i != -1; i = pre[edge[i^1].to])
{
edge[i].flow += Min;
edge[i^1].flow -= Min;
cost += edge[i].cost * Min;
}
}
}
int main()
{
while(scanf("%d%d", &N, &M) != EOF)
{
init();
getMap();
int cost;//最小费用
MCMF(source, sink, cost);
printf("%d\n", cost);
}
return 0;
}