Strong Defence
Problem Description
The Chief of the Galactic Empire has recently received some bad news from his spies. The Dark Lord is preparing to attack the Empire. His fleet of spaceships is ready for the first hyperjump.
It is well known that travelling in space is very simple. You just start from some star and make a series of hyperjumps to other stars. You can only jump from one star to another if they are connected with a special hyperjump tunnel, which is bidirectional, thus allowing to make a jump from one star that it connects to another. Of course, the tunnels are designed in such a way that there is the way to get from each star to any other one.
However, there is the way to block the hyperjumps to do this one must put a special battleship in the corresponding hypertunnel.
Of course, the Chief would like to block all hyperpaths from the star where the headquaters of the Dark Lord are located to the star where the capital of the Galactic Empire is. The resources of the Empire are almost unbounded, so it is easy to create as many battleships as needed. Unfortunately, there is one problem.
Each hyperjump blocking battleship must have a special crystal on board which allows him to stay in the hyperspace. There is a number of types of such crystals. The problem is that there is the way to destroy all battleships carrying some particular type of crystal.
Although it is known, that for each crystal type there is the way to destroy battleships powered by this crystal, there is hope that not all of those are known to Dark Lord engineers. So the Chief would like to use blocking ships in such a way that the following conditions are satisfied:
- for each crystal type, if all ships with other crystal types are destroyed, battle ships with this crystal type block hypertunnels in such a way, that there is no path from Dark Lord's star to Empire Capital star;
- the number of different crystal types used in ships is maximal possible;
- no two ships block the same hypertunnel.
You may consider that there is the unlimited number of crystal types available and crystals of each type available.
Input
The first line of the input file contains N - the number of stars in the Galaxy(2 <= N <= 400), M - the number of tunnels, S and T - numbers of stars where Dark Lord headquaters and Empire Capital are located respectively (S != T).
Next M lines contain two integer numbers each —— the numbers of the stars the corresponding tunnel connects. No tunnel connects a star to itself, no two stars are connected with more than one tunnel.
Output
Sample Input
4 4 1 4 1 2 1 3 2 4 3 4
Sample Output
2 2 1 22 3 4
一开始没读明白啥意思。。想到了最小边割集。。但是又要求水晶类型最多,直接分层图乱搞,没想到最后几分钟居然过了。。
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <map> #include <set> #include <queue> #include <stack> #include <bitset> using namespace std; #define PB push_back #define MP make_pair #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,l,h) for(int i=(l);i<=(h);++i) #define DWN(i,h,l) for(int i=(h);i>=(l);--i) #define MIN3(a,b,c) min(a,min(b,c)) #define CLR(vis,pos) memset(vis,pos,sizeof(vis)) #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LINF 1000000000000000000LL #define eps 1e-8 typedef long long ll; const int maxn=11111; int n,m,s,t; map< pair<int,int>,int> edge; vector<int> e[maxn]; int dis[maxn]; int vis[maxn]; queue <int> q; vector<int> ans[maxn]; int main() { cin>>n>>m>>s>>t; int u,v; REP(i,m){ scanf("%d%d",&u,&v); edge[MP(u,v)]=i+1; edge[MP(v,u)]=i+1; e[u].PB(v); e[v].PB(u); } CLR(dis,0x3f); while(!q.empty()) q.pop(); CLR(vis,0); dis[s]=0; q.push(s); vis[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=0;i<e[u].size();i++){ int v=e[u][i],w=1; if(dis[v]>=dis[u]+w){ dis[v]=dis[u]+w; if (!vis[v]){ vis[v]=1; q.push(v); } } } } cout<<dis[t]<<endl; FOR(i,0,maxn) ans[i].clear(); FOR(i,1,dis[t]){ FOR(j,1,n){ if(dis[j]==i){ REP(k,e[j].size()){ int v=e[j][k]; if(dis[v]<dis[j]){ int tmp=edge[MP(v,j)]; ans[i].PB(tmp); } } } } } FOR(i,1,dis[t]){ if(ans[i].size()==0) continue; cout<<ans[i].size(); REP(j,ans[i].size()) cout<<" "<<ans[i][j]; cout<<endl; } return 0; }