http://acm.sgu.ru/problem.php?contest=0&problem=242
网络流+打印路径
原点和人建立权为1的边,人和学校建立权为1的边,学校和汇点建权为2的边
最大流是2*k则yes,否则no
顺便附上修改自他人的带各种优化的Dinic模板~
1 /** 2 *网络流+打印路径 3 *原点和人建立权为1的边,学校和汇点建权为2的边 4 *最大流是2*k则yes,否则no 5 * 6 *@Author: xysmlx xiaohai 7 */ 8 //#pragma comment(linker, "/STACK:102400000,102400000") 9 #include<cstdio> 10 #include<iostream> 11 #include<cstring> 12 #include<string> 13 #include<cmath> 14 #include<set> 15 #include<list> 16 #include<map> 17 #include<iterator> 18 #include<cstdlib> 19 #include<vector> 20 #include<queue> 21 #include<stack> 22 #include<algorithm> 23 #include<functional> 24 using namespace std; 25 typedef long long LL; 26 #define ROUND(x) round(x) 27 #define FLOOR(x) floor(x) 28 #define CEIL(x) ceil(x) 29 const int maxn=510; 30 const int inf=0x3f3f3f3f; 31 const LL inf64=0x3f3f3f3f3f3f3f3fLL; 32 const double INF=1e30; 33 const double eps=1e-6; 34 35 /** 36 *最大流:加各种优化的Dinic算法($O(V^2E)$) 37 *输入:图(链式前向星),n(顶点个数,包含源汇),st(源),ed(汇) 38 *输出:MaxFlow()(最大流) 39 */ 40 //const int maxn=0; 41 const int maxm=50010; 42 //const int inf=0x3f3f3f3f; 43 struct Edge 44 { 45 int v; 46 int cap; 47 int next; 48 } edge[maxm]; 49 int head[maxn],edgeNum;//需初始化 50 int n,m,d[maxn],cur[maxn]; 51 int st,ed; 52 void addSubEdge(int u,int v,int cap) 53 { 54 edge[edgeNum].v=v; 55 edge[edgeNum].cap=cap; 56 edge[edgeNum].next=head[u]; 57 head[u]=edgeNum++; 58 cur[u]=head[u]; 59 } 60 void addEdge(int u,int v,int cap) 61 { 62 addSubEdge(u,v,cap); 63 addSubEdge(v,u,0);//注意加反向0边 64 } 65 bool BFS() 66 { 67 queue<int> Q; 68 memset(d, -1, sizeof(d)); 69 Q.push(st); 70 d[st]=0; 71 while (!Q.empty()) 72 { 73 int u=Q.front(); 74 Q.pop(); 75 for(int i=head[u]; i!=-1; i=edge[i].next) 76 { 77 int v=edge[i].v; 78 int cap=edge[i].cap; 79 if(cap&&d[v]==-1) 80 { 81 Q.push(v); 82 d[v]=d[u]+1; 83 if(v==ed) return 1; 84 } 85 } 86 } 87 return false; 88 } 89 int Aug(int u, int a) 90 { 91 if (u==ed) return a; 92 int aug=0, delta; 93 for(int &i=cur[u]; i!=-1; i=edge[i].next) 94 { 95 int v=edge[i].v; 96 int cap=edge[i].cap; 97 if (cap && d[v]==d[u]+1) 98 { 99 delta = Aug(v, min(a,cap)); 100 if (delta) 101 { 102 edge[i].cap -= delta; 103 edge[i^1].cap += delta; 104 aug += delta; 105 if (!(a-=delta)) break; 106 } 107 } 108 } 109 if (!aug) d[u]=-1; 110 return aug; 111 } 112 int MaxFlow() 113 { 114 int flow=0; 115 while (BFS()) 116 { 117 memcpy(cur,head,sizeof(int)*(n+1)); 118 flow += Aug(st,inf); 119 } 120 return flow; 121 } 122 123 int N,M; 124 void init() 125 { 126 memset(head,-1,sizeof(head)); 127 edgeNum=0; 128 st=0,ed=N+M+1; 129 n=N+M+1; 130 } 131 void input() 132 { 133 for(int i=1;i<=N;i++) 134 { 135 addEdge(st,i,1); 136 int u,v; 137 scanf("%d",&u); 138 for(int j=0;j<u;j++) 139 { 140 scanf("%d",&v); 141 addEdge(i,N+v,1); 142 } 143 } 144 for(int i=1;i<=M;i++) addEdge(N+i,ed,2); 145 } 146 void solve() 147 { 148 int f=MaxFlow(); 149 if(f!=2*M) 150 { 151 puts("NO"); 152 return; 153 } 154 puts("YES"); 155 for(int v=1;v<=M;v++) 156 { 157 printf("2"); 158 for(int i=head[N+v];i!=-1;i=edge[i].next) 159 { 160 if((i&1)&&edge[i].cap==1) printf(" %d",edge[i].v); 161 } 162 puts(""); 163 } 164 } 165 int main() 166 { 167 // std::ios_base::sync_with_stdio(false); 168 // freopen("in.cpp","r",stdin); 169 while(~scanf("%d%d",&N,&M)) 170 { 171 init(); 172 input(); 173 solve(); 174 } 175 return 0; 176 }