#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e4 + 5, M = 2e5 + 5, INF = 1e8;
int h[N], e[M], ne[M], w[M], idx, d[N], q[N], n, m, S, T, cur[N], gap[N];
long long maxflow;
void add(int a, int b, int c)
{
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
e[idx] = a, ne[idx] = h[b], w[idx] = 0, h[b] = idx ++;
}
void bfs()
{
int hh = 0, tt = 0;
memset(d, -1, sizeof d);
q[0] = T, d[T] = 0, cur[T] = h[T], gap[0] = 1;
while (hh <= tt)
{
int t = q[hh ++ ];
for (int i = h[t]; ~i; i = ne[i])
{
int ver = e[i];
if (d[ver] == -1 && !w[i])
{
cur[ver] = h[ver];
d[ver] = d[t] + 1;
gap[d[ver]] ++;
q[++ tt] = ver;
}
}
}
}
int min(int a, long long b)
{
return a < b ? a : b;
}
long long find(int u, long long limit)
{
if (u == T)
{
maxflow += limit;
return limit;
}
int flow = 0;
for (int i = cur[u]; ~i; i = ne[i])
{
cur[u] = i;
int ver = e[i];
if (d[ver] + 1 == d[u] && w[i])
{
int t = find (ver, min(w[i], limit - flow));
w[i] -= t, w[i ^ 1] += t, flow += t;
if (flow == limit) return flow;
}
}
-- gap[d[u]];
if (gap[d[u]] == 0) d[S] = n + 1;
d[u] ++;
gap[d[u]] ++;
return flow;
}
long long ISAP()
{
bfs();
while(d[S] < n)
{
memcpy(cur, h, sizeof h);
find(S, INF);
}
return maxflow;
}
int main()
{
scanf("%d%d%d%d", &n, &m, &S, &T);
memset(h, -1, sizeof h);
while (m -- )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
}
printf("%lld\n", ISAP());
return 0;
}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 5010, M = 100010, INF = 1e8;
int n, m, S, T;
int h[N], e[M], f[M], w[M], ne[M], idx;
int q[N], d[N], pre[N], incf[N];
bool st[N];
void add(int a, int b, int c, int d)
{
e[idx] = b, f[idx] = c, w[idx] = d, ne[idx] = h[a], h[a] = idx ++ ;
e[idx] = a, f[idx] = 0, w[idx] = -d, ne[idx] = h[b], h[b] = idx ++ ;
}
bool spfa()
{
int hh = 0, tt = 1;
memset(d, 0x3f, sizeof d);
memset(incf, 0, sizeof incf);
q[0] = S, d[S] = 0, incf[S] = INF;
while (hh != tt)
{
int t = q[hh ++ ];
if (hh == N) hh = 0;
st[t] = false;
for (int i = h[t]; ~i; i = ne[i])
{
int ver = e[i];
if (f[i] && d[ver] > d[t] + w[i])
{
d[ver] = d[t] + w[i];
pre[ver] = i;
incf[ver] = min(f[i], incf[t]);
if (!st[ver])
{
q[tt ++ ] = ver;
if (tt == N) tt = 0;
st[ver] = true;
}
}
}
}
return incf[T] > 0;
}
void EK(int& flow, int& cost)
{
flow = cost = 0;
while (spfa())
{
int t = incf[T];
flow += t, cost += t * d[T];
for (int i = T; i != S; i = e[pre[i] ^ 1])
{
f[pre[i]] -= t;
f[pre[i] ^ 1] += t;
}
}
}
int main()
{
scanf("%d%d%d%d", &n, &m, &S, &T);
memset(h, -1, sizeof h);
while (m -- )
{
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
add(a, b, c, d);
}
int flow, cost;
EK(flow, cost);
printf("%d %d\n", flow, cost);
return 0;
}
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 1.5e5 + 5;
int h[N], e[N], ne[N], w[N], idx, n, m;
int dis[N];
bool st[N];
void add(int a, int b, int c)
{
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}
int dijkstra()
{
memset(dis, 0x3f, sizeof dis);
dis[1] = 0;
priority_queue <PII, vector<PII>, greater<PII>> heap;
heap.push({0, 1});
while(heap.size())
{
auto t = heap.top();
heap.pop();
int ver = t.second;
if(st[ver]) continue;
st[ver] = true;
for (int i = h[ver]; i != -1; i = ne[i])
{
int j = e[i];
if (dis[j] > dis[ver] + w[i])
{
dis[j] = dis[ver] + w[i];
heap.push({dis[j], j});
}
}
}
if (dis[n] == 0x3f3f3f3f) return -1;
return dis[n];
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
while (m -- )
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
}
cout << dijkstra() << endl;
}
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 510, M = 10010;
struct Edge
{
int a, b, c;
}edges[M];
int n, m, k;
int dist[N];
int last[N];
void bellman_ford()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
for (int i = 0; i < k; i ++ )
{
memcpy(last, dist, sizeof dist);
for (int j = 0; j < m; j ++ )
{
auto e = edges[j];
dist[e.b] = min(dist[e.b], last[e.a] + e.c);
}
}
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
for (int i = 0; i < m; i ++ )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edges[i] = {a, b, c};
}
bellman_ford();
if (dist[n] > 0x3f3f3f3f / 2) puts("impossible");
else printf("%d\n", dist[n]);
return 0;
}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510, INF = 0x3f3f3f3f;
int g[N][N], dist[N], n, m;
bool st[N];
int prim()
{
memset(dist, 0x3f, sizeof dist);
int res = 0;
for (int i = 0; i < n; i ++ )
{
int t = -1;
for (int j = 1; j <= n; j ++ )
if (!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
if (i && dist[t] == INF) return INF;
if (i) res += dist[t];
st[t] = true;
for (int j = 1; j <= n; j ++ ) dist[j] = min(dist[j], g[t][j]);
}
return res;
}
int main()
{
cin >> n >> m;
memset(g, 0x3f, sizeof g);
while (m -- )
{
int a, b, c;
cin >> a >> b >> c;
g[a][b] = g[b][a] = min(g[a][b], c);
}
int t = prim();
if (t == INF) puts("impossible");
else cout << t << endl;
}
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 20, M = 1 << N;
int g[N][N], f[M][N];
int main()
{
int n = 0;
cin >> n;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
cin >> g[i][j];
memset(f, 0x3f, sizeof f);
f[1][0] = 0;
for (int i = 0; i < 1 << n; i ++ )
for (int j = 0; j < n; j ++ )
if ((i >> j) & 1)
for (int k = 0; k < n; k ++ )
if ((i >> k) & 1)
f[i][j] = min(f[i][j], f[i - (1 << j)][k] + g[k][j]);
cout << f[(1 << n) - 1][n - 1] << endl;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100100, M = 400100;
int h[N],e[M],ne[M],idx;
int ans[N*2],cnt;
bool used[M];
int din[N],dout[N];
int n,m,ver;
void add(int a,int b){
e[idx] = b,ne[idx] = h[a],h[a] = idx++;
}
void dfs(int u){
for(int &i = h[u]; ~i; ){
if(used[i]){ //如果这条边用过了
i = ne[i]; //删除这条边
continue;
}
used[i] = true; //标记这条边已使用
if(ver == 1) used[i^1] = true; //如果是无向图,那么这条边的反向边也要标记使用过了
int t;
if(ver == 1){
t = i/2 + 1;
if(i&1) t = -t; //(0,1) (2,3) (4,5) 奇数编号是返回的边
}else t = i+1;
int j = e[i];
i = ne[i];
dfs(j);
ans[cnt++] = t;
}
}
int main()
{
scanf("%d%d%d",&ver,&n,&m);
memset(h,-1,sizeof h);
for(int i = 0; i<m; i++){
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
if(ver == 1) add(b,a); //无向边
din[b]++, dout[a]++;
}
if(ver == 1){
for(int i = 1; i<=n; i++){
if(din[i]+dout[i] &1){
//无向图含欧拉回路的充要条件是每个点的度都为偶数
puts("NO");
return 0;
}
}
}else{
for(int i = 1; i<=n; i++){
if(din[i] != dout[i]){
//有向图含欧拉回路的充要条件是每个点的入度等于出度
puts("NO");
return 0;
}
}
}
for(int i = 1; i<=n; i++){
if(~h[i]) {
dfs(i);
break;
}
}
if(cnt < m){
puts("NO");
return 0;
}
puts("YES");
for(int i = cnt-1; i>=0; --i){
cout<<ans[i]<<" ";
}
return 0;
}